Cam*_*mel 6 ruby ruby-on-rails mongodb mongoid
我在Mongoid中有很多可选字段,例如:
field :key, type: String
field :element, type: String
field :rect, type: Array
Run Code Online (Sandbox Code Playgroud)
如果我返回这个模型的json,其中只有一个填充,我会得到null
所有其他字段的值.我该如何删除这些字段?
我的模型有嵌套属性,这意味着空值可以在几个级别上.
澄清:
我需要一种方法从模型的json表示中删除空字段,包括所有嵌套属性中的空字段.
代码示例:
1.9.3-p0 :005 > u=Muse.new(:key=>'ram').to_json
=> "{\"_id\":\"4f1ced749c2ee4219d000003\",\"element\":null,\"key\":\"ram\",\"rect\":null}"
Run Code Online (Sandbox Code Playgroud)
默认情况下mongoid
,可以删除空字段.如果您让某些字段为空,mongoid
则会在插入时删除它们.
在下面的例子中,我省略了fields元素&rect
class User
include Mongoid::Document
field :key, type: String
field :element, type: String
field :rect, type: Array
embeds_one :home
end
>> u=User.new(:key=>'ram').to_json
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"key":"ram"}"
Run Code Online (Sandbox Code Playgroud)
它完美无缺.但是如果你在场上放一个零值
>> u=User.new(:key=>'ram',:element=>nil).to_json
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"User","key":"ram","element":null}"
Run Code Online (Sandbox Code Playgroud)
它被插入.我认为这是你代码中的确切问题.因此,您可以通过使用as_json
和删除nil字段转换JSON哈希表示来解决此问题
x=u.as_json.reject! {|k,v| v.nil?}
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"User","key":"ram"}"
Run Code Online (Sandbox Code Playgroud)
但要进入内在层面,你无法使用as_json
.检查以下代码
>>h=Home.new(:address=>'xxxx',:dummy=>nil)
>>u.home = h
>>x=u.as_json.reject! {|k,v| v.nil?}
=>{"_id"=>BSON::ObjectId('4f1c39b4b356f82e4a000003'), "_type"=>"User","key":"ram","home"=>#<Home _id: 4f1c3c5db356f82e4a000004,address:'xxxx' , dummy: nil >}
Run Code Online (Sandbox Code Playgroud)
现在你看到嵌入式doc house里面的字段虚拟仍然是零.所以我最好的建议是不要将db值设为db.为此,before_save
在模型上进行回调(也嵌入)并删除空字段.
另外,我将向您展示如何从嵌套对象中删除nil字段.如果没有其他办法,请使用它
我们可以使用attributes
mongoid模型来获取对象的哈希表示,包括嵌套级别
x=u.attributes
=> {"_id"=>BSON::ObjectId4f1c39b4b356f82e4a000003,"key"=>"ram","element"=>nil,"home"=>{"address"=>"xxxx", "_id"=>BSON::ObjectId4f1c3c5db356f82e4a000004,"dummy"=>nil}}
Run Code Online (Sandbox Code Playgroud)
并且你必须找到mongoid对象里面有任何Hash,如果有的话,我们也必须使用reject! {|k,v| v.nil?}
那个Hash
整理所有
def to_json(obj)
obj.reject! {|k,v| v.nil?}
obj.find_all {|x| x[1].class==BSON::OrderedHash}.each do |arr|
obj[arr[0]] = to_json(arr[1])
end
obj
end
Run Code Online (Sandbox Code Playgroud)
并使用模型的属性调用它,
>> to_json u.attributes
=> {"_id"=>BSON::ObjectId4f1c39b4b356f82e4a000003,"key"=>"ram","home"=>{"address"=>"xxxx", "_id"=>BSON::ObjectId4f1c3c5db356f82e4a000004}}
Run Code Online (Sandbox Code Playgroud)
就这样.希望能帮助到你