Динамические атрибуты с Rails и Mongoid

Я изучаю MongoDB через mongoid Ruby gem с Rails (Rails 3 beta 3), и я пытаюсь придумать способ создания динамических атрибутов на модели на основе полей из другой модели, для которой я думал, что база данных без схемы будет хорошим выбором.

Так, например, у меня были бы модели:

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

Я хочу взять атрибут "info_needed" модели учетной записи и создать динамические атрибуты на модели-члене на основе того, что внутри. Если клуб.info_needed был ["first_name", "last_name"], я пытаюсь создать форму, которая сохранит атрибуты first_name и last_name в модели-члене.

однако, на практике, я просто продолжаю получать ошибки "undefined method first_name=" в модели-члене при попытке сделать это. Я знаю, что MongoDB может обрабатывать динамические атрибуты для каждой записи, но как я могу заставить Mongoid сделать это без ошибки неопределенного метода?

4 ответов


Mongoid на самом деле не поддерживают его.

У меня есть попросил это в Монгольской группе себя.

это возможно при создании нового документа, например:

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


Mongoid теперь поддерживает динамические поля. Их документацию можно найти здесь: http://mongoid.org/en/mongoid/docs/documents.html#dynamic_fields

в основном он предупреждает, что вы должны быть немного осторожны, как вы устанавливаете динамические поля, поскольку это вызовет ошибку метода no, если вы попытаетесь использовать методы getter и setter для поля, которое не существовало в документе.

[],[]= ярлыки для read_attribute(),write_attribute() , и должны быть используется, если вы не установили dynamic_attributes = true в своем ./config/mongoid.yml file, в противном случае вы получите ошибку метода no.

задание 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")

обязательно allow_dynamic_fields: true на mongoid.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

...

интересная статья о динамических атрибутах с Mongoid и Rails 3.1: http://paul-wong-jr.blogspot.com/2012/03/dynamic-attributes-and-mongodbmongoid.html

чтобы получить доступ только к парам динамических ключей/значений или именам динамических атрибутов, см. Также: список динамических атрибутов в модели Mongoid