14

我在 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很好,因为我要存储的内容没有固定的模式,并且因一件事而异。

好的,但是,我不能对哈希$set中的键/值对使用相同的点语法。:info[1]

thing.set("info.endDate"=>Time.now) 

引发Mongoid::Errors::UnknownAttribute错误。

它告诉我我必须Mongoid::Attributes::Dynamic在我的模型中加入才能做到这一点,但这对我来说似乎不合适。哈希字段类型的重点似乎是允许您使用没有固定模式的数据。我似乎不必包含一个特殊的“动态属性”模块来使用哈希字段。

所以现在,我正在使用常规的旧[]语法更新值,然后调用save模型,如下所示:

thing.info[:endDate] = Time.now
thing.save

但很多时候,它会更好地体现$set价值。是否有其他语法用于设置哈希字段值?我对上述错误消息和动态属性有误吗?我现在是否坚持对哈希字段进行两步更新?

[1] 诚然,我最近从 mongomapper 迁移过来,所以我对这种语法的期望部分是因为之前在 mongomapper 中能够做到这一点。

4

2 回答 2

13

哈希字段的作用是,它可以是动态的,只要你想要。因此,为了防止由代码中的错误导致的意外字段污染您的数据库架构,默认情况下禁用此功能。

不,您根本不会对哈希使用两步更新!

[],[]= 是read_attribute()and的快捷方式,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 动态字段 - 没有方法错误

Rails 和 Mongoid 的动态属性

于 2016-04-07T13:38:38.787 回答
1

我认为您以错误的方式传递参数。用逗号替换箭头符号

你可以改变这个,它会工作

thing.set("info.endDate", Time.now) 
于 2016-04-06T06:13:44.813 回答