15

我正在通过带有 Rails(Rails 3 beta 3)的 Mongoid Ruby gem 学习 MongoDB,并且我试图想出一种方法来基于来自另一个模型的字段在模型上创建动态属性,我认为这是一个模式-少数据库将是一个不错的选择。

例如,我有模型:

class Account
  include Mongoid::Document

  field :name, :type => String
  field :token, :type => String
  field :info_needed, :type => Array

  embeds_many :members
end

class Member
  include Mongoid::Document

  embedded_in :account, :inverse_of => :members

end

我正在寻找 Account 模型的“info_needed”属性,并根据里面的内容在 Member 模型上创建动态属性。如果 club.info_needed 是 ["first_name", "last_name"],我正在尝试创建一个将 first_name 和 last_name 属性保存到 Member 模型的表单。

但是,在实践中,我只是在尝试执行此操作时在 Member 模型上不断收到“未定义的方法 first_name =”错误。我知道 MongoDB 可以处理每条记录的动态属性,但是如何让 Mongoid 在没有未定义方法错误的情况下执行此操作?

4

4 回答 4

30

Mongoid 现在支持动态字段。他们的文档可以在这里找到:http: //mongoid.org/en/mongoid/docs/documents.html#dynamic_fields

基本上,它警告您必须稍微小心如何设置动态字段,因为如果您尝试对文档中不存在的字段使用 getter 和 setter 方法,则会引发 no method 错误。

dynamic_attributes = true[],[]= 是 read_attribute(),write_attribute() 的快捷方式,如果你没有在你的中设置,应该使用./config/mongoid.yml file,否则你会得到一个 no method 错误。

设置allow_dynamic_fields: true可能有风险,因为您可能会使用由代码中的错误引起的意外字段污染您的数据/模式。false将其设置为并明确使用 [],[]=可能更安全

# Raise a NoMethodError if value isn't set.
person.gender
person.gender = "Male"

# Retrieve a dynamic field safely.
person[:gender]
person.read_attribute(:gender)

# Write a dynamic field safely.
person[:gender] = "Male"
person.write_attribute(:gender, "Male")
于 2011-04-07T18:23:05.440 回答
8

请务必设置allow_dynamic_fields: truemongoid.yml. 例子:

defaults: &defaults
  allow_dynamic_fields: true
  parameterize_keys: true
  persist_in_safe_mode: true
  raise_not_found_error: true
  reconnect_time: 3
  use_object_ids: false

development:
  <<: *defaults

...
于 2010-05-19T19:30:53.273 回答
2

关于 Mongoid 和 Rails 3.1 的动态属性的有趣文章:http: //paul-wong-jr.blogspot.com/2012/03/dynamic-attributes-and-mongodbmongoid.html

要仅访问动态键/值对或动态属性名称,另请参阅: 列出 Mongoid 模型中的动态属性

于 2012-07-23T00:12:29.990 回答
1

Mongoid 并不真正支持它。

我碰巧自己在 Mongoid 小组问过这个问题。

当您创建新文档时,它是可能的,如下所示:

account = Account.new(:some_dynamic_field => "...")

于 2010-05-24T14:30:38.963 回答