问题描述
我在Mongoid中有很多可选字段,例如:
I have a lot of optional fields in Mongoid, like:
field :key, type: String
field :element, type: String
field :rect, type: Array
如果我返回一个仅填充其中一个的此模型的json,则在所有其他字段上都将得到null
值.如何删除这些字段?
If I return a json of this model with only one of them filled I get null
values on all the other fields. How can I remove those fields?
我的模型具有嵌套属性,这意味着空值可以处于多个级别.
My model has nested attributes, which means null values can be on several levels.
说明:
我需要一种从模型的json表示中删除空字段的方法,包括所有嵌套属性中的空字段.
I need a way to remove null fields from the json representation of a model, including null fields in all nested attributes.
代码示例:
1.9.3-p0 :005 > u=Muse.new(:key=>'ram').to_json
=> "{\"_id\":\"4f1ced749c2ee4219d000003\",\"element\":null,\"key\":\"ram\",\"rect\":null}"
推荐答案
默认情况下,mongoid
具有删除空字段的功能.如果您将某些字段留空,mongoid
将在插入时将其删除.
By default mongoid
has the ability to remove empty fields. If you let some fields empty, mongoid
will removes them on insert.
在下面的示例中,我省略了fields元素& rect
in the below example, I left out the fields element & 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"}"
,并且效果很好.但是,如果您在字段
and it works perfectly. But if you put a nil value in the field
>> u=User.new(:key=>'ram',:element=>nil).to_json
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"User","key":"ram","element":null}"
它被插入.我认为那是您代码中的确切问题.因此,您可以通过使用as_json
转换JSON哈希表示并删除nil字段
It gets inserted. I assume that's the exact problem in your code. So you can work around this by converting JSON hash representation using as_json
and remove the nil fields
x=u.as_json.reject! {|k,v| v.nil?}
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"User","key":"ram"}"
但是要进入内部层次,您不能使用as_json
.检查以下代码
But to go to the inner levels, you cannot use as_json
. check the below code
>>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 >}
现在,您看到嵌入式文档库中的字段虚拟对象仍为nil.因此,我最好的建议是不要将nil值放在db中.为此,在模型上也嵌入before_save
回调(也嵌入)并删除空白字段.
Now you see the field dummy inside the embedded doc house is still with nil. so my best advice is Dont put the nil values in db at all. To do that put a before_save
callback on your models (embedded too) and remove the empty fields.
我还将向您展示如何从嵌套对象中删除nil个字段.如果没有其他方法,请使用它
Also I will show you how to remove nil fields from nested objects too. Use it if there is no other way
我们可以使用mongoid模型的attributes
来获取对象的哈希表示形式,包括嵌套级别
We can use attributes
of mongoid model to get the hash representation of the object including the nested levels
x=u.attributes
=> {"_id"=>BSON::ObjectId4f1c39b4b356f82e4a000003,"key"=>"ram","element"=>nil,"home"=>{"address"=>"xxxx", "_id"=>BSON::ObjectId4f1c3c5db356f82e4a000004,"dummy"=>nil}}
,您必须找到在mongoid对象中是否存在任何哈希,如果有的话,我们也必须在该哈希上使用reject! {|k,v| v.nil?}
and you have to find is there any Hash inside the mongoid object, if one, we have to use the reject! {|k,v| v.nil?}
on that Hash too
将所有内容组合在一起
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
并使用模型的属性调用它,
and call this with attributes of the model,
>> to_json u.attributes
=> {"_id"=>BSON::ObjectId4f1c39b4b356f82e4a000003,"key"=>"ram","home"=>{"address"=>"xxxx", "_id"=>BSON::ObjectId4f1c3c5db356f82e4a000004}}
仅此而已.希望对您有帮助
Thats all. Hope it helps
这篇关于Rails + Mongoid-不要在JSON中返回nil值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!