设置 mongoid 哈希字段值
setting mongoid hash field values
我在一个 Rails 项目(都是 4.0.x)中使用 Mongoid,并且我有一个包含存储一些无模式数据的哈希字段的文档。
class Thing
field :name, type: String
field :mass, type: Integer
field :info, type: Hash
end
使用此设置,我可以查询具有键 :endDate
的内容,如下所示:
Thing.where("info.endDate"=>{'$exists'=>true})
这一切都非常方便。为这个 :info
字段使用哈希字段很好,因为我要存储的内容没有固定的模式,并且因事物而异。
好的,但是,我不能对 :info
散列中的 $set
key/value 对使用相同的点语法。 [1]
thing.set("info.endDate"=>Time.now)
引发 Mongoid::Errors::UnknownAttribute
错误。
它告诉我必须在我的模型中包含 Mongoid::Attributes::Dynamic
才能执行此操作,但这 似乎 不适合我。 The point of the hash field type 似乎允许您使用没有固定模式的数据。似乎我不必包含一个特殊的 "dynamic attributes" 模块来使用散列字段。
所以现在,我正在使用常规的旧 []
语法更新值,然后在模型上调用 save
,如下所示:
thing.info[:endDate] = Time.now
thing.save
但很多时候只是 $set
值会更好。是否有其他语法用于设置哈希字段值?上面的错误信息和动态属性是错误的,我错了吗?我现在是否坚持对哈希字段进行两步更新?
[1] 不可否认,我最近从 mongomapper 迁移过来,所以我对这种语法的期望部分是由于之前在 mongomapper 中能够做到这一点。
我认为你传递参数的方式不对。 用逗号替换箭头符号
你可以改成这个,它会起作用
thing.set("info.endDate", Time.now)
哈希字段的特点是,它可以随心所欲地动态变化。因此,为了防止代码中的错误导致意外字段污染您的数据库模式,默认情况下禁用此功能。
不,您根本不会为哈希使用两步更新!
[],[]= 是 read_attribute()
和 write_attribute()
的快捷方式,如果您不包含 Mongoid::Attributes::Dynamic
,则应使用它。如果您尝试在未启用动态属性的情况下使用 $set
,您将收到无方法错误,因为它不会将您的动态属性视为定义的属性。
如果您阅读 Mongoid::Attributes::Dynamic 的源代码,您会发现这是添加动态属性功能所必需的。
要通过包含 Mongoid::Attributes::Dynamic
来更新值,您需要执行以下步骤:
thing = Thing.first
thing.set("info.endDate" => Time.now)
thing.reload # This will update the current variable
否则,如果您需要,可以轻松跳过此步骤并通过两步法进行值更新
我希望这对您的查询有所帮助。
来源:
Rails mongoid dynamic fields - no method error
Dynamic attributes with Rails and Mongoid
我在一个 Rails 项目(都是 4.0.x)中使用 Mongoid,并且我有一个包含存储一些无模式数据的哈希字段的文档。
class Thing
field :name, type: String
field :mass, type: Integer
field :info, type: Hash
end
使用此设置,我可以查询具有键 :endDate
的内容,如下所示:
Thing.where("info.endDate"=>{'$exists'=>true})
这一切都非常方便。为这个 :info
字段使用哈希字段很好,因为我要存储的内容没有固定的模式,并且因事物而异。
好的,但是,我不能对 :info
散列中的 $set
key/value 对使用相同的点语法。 [1]
thing.set("info.endDate"=>Time.now)
引发 Mongoid::Errors::UnknownAttribute
错误。
它告诉我必须在我的模型中包含 Mongoid::Attributes::Dynamic
才能执行此操作,但这 似乎 不适合我。 The point of the hash field type 似乎允许您使用没有固定模式的数据。似乎我不必包含一个特殊的 "dynamic attributes" 模块来使用散列字段。
所以现在,我正在使用常规的旧 []
语法更新值,然后在模型上调用 save
,如下所示:
thing.info[:endDate] = Time.now
thing.save
但很多时候只是 $set
值会更好。是否有其他语法用于设置哈希字段值?上面的错误信息和动态属性是错误的,我错了吗?我现在是否坚持对哈希字段进行两步更新?
[1] 不可否认,我最近从 mongomapper 迁移过来,所以我对这种语法的期望部分是由于之前在 mongomapper 中能够做到这一点。
我认为你传递参数的方式不对。 用逗号替换箭头符号
你可以改成这个,它会起作用
thing.set("info.endDate", Time.now)
哈希字段的特点是,它可以随心所欲地动态变化。因此,为了防止代码中的错误导致意外字段污染您的数据库模式,默认情况下禁用此功能。
不,您根本不会为哈希使用两步更新!
[],[]= 是 read_attribute()
和 write_attribute()
的快捷方式,如果您不包含 Mongoid::Attributes::Dynamic
,则应使用它。如果您尝试在未启用动态属性的情况下使用 $set
,您将收到无方法错误,因为它不会将您的动态属性视为定义的属性。
如果您阅读 Mongoid::Attributes::Dynamic 的源代码,您会发现这是添加动态属性功能所必需的。
要通过包含 Mongoid::Attributes::Dynamic
来更新值,您需要执行以下步骤:
thing = Thing.first
thing.set("info.endDate" => Time.now)
thing.reload # This will update the current variable
否则,如果您需要,可以轻松跳过此步骤并通过两步法进行值更新
我希望这对您的查询有所帮助。
来源:
Rails mongoid dynamic fields - no method error
Dynamic attributes with Rails and Mongoid