设置mongoid哈希字段值

时间:2016-03-31 04:38:48

标签: ruby-on-rails mongodb mongoid mongoid4

我在Rails项目中使用Mongoid(均为4.0.x),并且我有一个带有哈希字段的文档,该字段存储了一些无模式数据。

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才能执行此操作,但这对我来说似乎 The point of the hash field type似乎是允许您处理没有固定架构的数据。我似乎不应该包含一个特殊的动态属性"模块使用哈希字段。

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

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

但是很多时候它只会$set价值更好。是否有其他语法来设置哈希字段值?我错误的上述错误消息和动态属性是错误的?我暂时不想对哈希字段进行两步更新吗?

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

2 个答案:

答案 0 :(得分:9)

Hash字段的内容是,它可以是您想要的动态。因此,为了防止因代码中的错误导致的非预期字段污染数据库架构,默认情况下会禁用此功能。

不,你根本没有使用哈希的两步更新!

[],[] =是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

答案 1 :(得分:1)

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

您可以更改为此功能

thing.set("info.endDate", Time.now)