【问题标题】:Dynamic attributes with Rails and MongoidRails 和 Mongoid 的动态属性
【发布时间】:2010-04-23 14:16:26
【问题描述】:

我正在通过带有 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 做到这一点而不会出现未定义的方法错误?

【问题讨论】:

  • 请您在下面选择我的答案作为答案,因为它比当前选择的答案更准确。

标签: ruby-on-rails mongodb mongoid dynamic-attributes


【解决方案1】:

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

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

[],[]= 是 read_attribute(),write_attribute() 的快捷方式,如果你没有在 ./config/mongoid.yml file 中设置 dynamic_attributes = true ,则应该使用它,否则你会得到一个 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")

【讨论】:

  • 在 4.0 中被移除
【解决方案2】:

请务必在mongoid.yml 中设置allow_dynamic_fields: true。示例:

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

...

【讨论】:

  • 是的,我已经这样做了,但仍然遇到问题。如果您已经这样做了,并且它一直在为您工作,那么自我发布此问题以来,mongoid 可能已更新。
  • 设置allow_dynamic_attributes: true 的缺点是它是针对每个数据库的,并且您可能会使用代码中的错误导致的意外字段污染您的架构。将其设置为 false 并有意识地使用 [],[]= 可能更安全
【解决方案3】:

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

要仅访问动态键/值对或动态属性名称,另请参阅: List dynamic attributes in a Mongoid Model

【讨论】:

    【解决方案4】:

    Mongoid 并不真正支持它。

    我自己在 Mongoid 组碰巧有 asked 这个。

    创建新文档时可以这样:

    account = Account.new(:some_dynamic_field =&gt; "...")

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 2012-08-12
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多