默认情况下mongoid
具有删除空字段的能力。如果您让某些字段为空,mongoid
将在插入时删除它们。
在下面的示例中,我省略了字段元素和矩形
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"}"
它工作得很好。但是如果你在字段中输入一个零值
>> u=User.new(:key=>'ram',:element=>nil).to_json
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"User","key":"ram","element":null}"
它被插入。我认为这就是您的代码中的确切问题。因此,您可以通过使用转换 JSON 哈希表示来解决此问题as_json
并删除 nil 字段
x=u.as_json.reject! {|k,v| v.nil?}
=> "{"_id":"4f1c3722b356f82e4a000001","_type":"User","key":"ram"}"
但要进入内部层次,你不能使用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 >}
现在您可以看到嵌入式文档室内的现场虚拟变量仍然为零。所以我最好的建议是根本不要将 nil 值放入 db 中。为此,请放置一个before_save
回调您的模型(也嵌入)并删除空字段。
我还将向您展示如何从嵌套对象中删除空字段。如果没有其他办法就使用它
我们可以用attributes
的 mongoid 模型来获取对象的哈希表示,包括嵌套级别
x=u.attributes
=> {"_id"=>BSON::ObjectId4f1c39b4b356f82e4a000003,"key"=>"ram","element"=>nil,"home"=>{"address"=>"xxxx", "_id"=>BSON::ObjectId4f1c3c5db356f82e4a000004,"dummy"=>nil}}
你必须找到 mongoid 对象内是否有哈希值,如果有,我们必须使用reject! {|k,v| v.nil?}
也在那个哈希上
把所有的放在一起
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
并用模型的属性来调用它,
>> to_json u.attributes
=> {"_id"=>BSON::ObjectId4f1c39b4b356f82e4a000003,"key"=>"ram","home"=>{"address"=>"xxxx", "_id"=>BSON::ObjectId4f1c3c5db356f82e4a000004}}
就这样。希望能帮助到你