设置 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