添加具有 nil 值的新动态属性
Posted
技术标签:
【中文标题】添加具有 nil 值的新动态属性【英文标题】:Add new dynamic attribute with nil value 【发布时间】:2021-01-15 06:03:26 【问题描述】:我在向 mongoid 文档添加新的动态属性时遇到问题,其值为 nil
class User
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Attributes::Dynamic
end
u = User.find(id)
u.write_attribute(:bar, nil)
puts u.bar
# => nil
u.save!
u = User.find(id)
puts u.bar
# => NoMethodError (undefined method `bar for #<User:0x00007fe87a97cfd8>)
添加具有除nil
以外的任何其他值的新属性都可以正常工作。
u = User.find(id)
u.write_attribute(:foo, "a")
puts u.foo
# => "a"
u.save!
u = User.find(id)
puts u.foo
# => "a"
这里有什么我遗漏的吗?
【问题讨论】:
【参考方案1】:您可以使用#set 将属性值设置为nil。见https://docs.mongodb.com/mongoid/master/tutorials/mongoid-persistence/#atomic。
irb(main):024:0> u.set(foo: nil)
D, [2020-10-05T21:31:20.167950 #18418] DEBUG -- : MONGODB | localhost:14400 req:15 conn:1:1 sconn:1088 | mongoid.update | STARTED | "update"=>"users", "ordered"=>true, "updates"=>["q"=>"_id"=>BSON::ObjectId('5f7bc8642c97a647f27735c6'), "u"=>"$set"=>"foo"=>nil], "$db"=>"mongoid", "lsid"=>"id"=><BSON::Binary:0x7620 type=uuid data=0x606db89de7a04adf...>
D, [2020-10-05T21:31:20.169268 #18418] DEBUG -- : MONGODB | localhost:14400 req:15 | mongoid.update | SUCCEEDED | 0.001s
=> #<User _id: 5f7bc8642c97a647f27735c6, created_at: 2020-10-06 01:29:08.638566093 UTC, updated_at: 2020-10-06 01:29:20.656350934 UTC, bar: nil, bar1: 1, foo: nil>
然后#attributes 按预期工作:
irb(main):023:0> User.find(u.id).attributes
D, [2020-10-05T21:30:18.758322 #18418] DEBUG -- : MONGODB | localhost:14400 req:14 conn:1:1 sconn:1088 | mongoid.find | STARTED | "find"=>"users", "filter"=>"_id"=>BSON::ObjectId('5f7bc8642c97a647f27735c6'), "$and"=>["_id"=>BSON::ObjectId('5f7bc8642c97a647f27735c6')], "$db"=>"mongoid", "lsid"=>"id"=><BSON::Binary:0x7620 type=uuid data=0x606db89de7a04adf...>
D, [2020-10-05T21:30:18.759791 #18418] DEBUG -- : MONGODB | localhost:14400 req:14 | mongoid.find | SUCCEEDED | 0.001s
=> "_id"=>BSON::ObjectId('5f7bc8642c97a647f27735c6'), "updated_at"=>2020-10-06 01:29:20.656 UTC, "created_at"=>2020-10-06 01:29:08.638 UTC, "bar1"=>1, "foo"=>nil
如果您认为 write_attribute 应该保留具有 nil 值的属性,您可以在 https://jira.mongodb.org/browse/MONGOID 创建一个工单来描述您的用例。
【讨论】:
【参考方案2】:Mongo::Attributes::Dynamic 的文档中提到了这一点:
如果文档中不存在该属性,Mongoid 将不会为您提供 getter 和 setter,并将强制执行正常的 method_missing 行为。在这种情况下,您必须使用其他提供的访问器方法:([] 和 []=) 或 (read_attribute 和 write_attribute)。
所以你可以使用user[:bar]
或user.read_attribute(:bar)
【讨论】:
我知道这一点,但在我的示例中,我使用write_attribute
设置一个新属性,我希望它在保存后可以访问,但当我将属性设置为无。
我不太了解 Mongo,你确定它的行为就像一个具有 nil 值的键存在吗?当您直接在 Mongo 中查找时会发生什么?这与查找 wss 根本没有设置的键时的行为相比如何?以上是关于添加具有 nil 值的新动态属性的主要内容,如果未能解决你的问题,请参考以下文章