Rails / ActiveRecord: has_one, assign_to и before_create - PullRequest
0 голосов
/ 16 июля 2010

Мне сложно понять, как лучше всего моделировать мои данные.В моем приложении Rails есть две следующие модели:

class Foo < ActiveRecord::Base
  belongs_to :active_bar, :class_name => 'Bar'
  accepts_nested_attributes_for :active_bar

  before_create do |f|
    f.active_bar.foo = f

    # Causes stack overflow!
    f.active_bar.save!
  end
end

class Bar < ActiveRecord::Base
  belongs_to :foo
end

test 'create with nested attributes' do
  f = Foo.create!(:name => 'foo-name', :active_bar_attributes => {:name => 'bar-name'})
  assert_equal 'foo-name', f.name
  assert_equal 'bar-name', f.active_bar.name
  assert_equal f, f.active_bar.foo

  f_id = f.to_param

  retrieved_f = Foo.find_by_id!(f_id)
  assert_equal retrieved_f, retrieved_f.active_bar.foo
end

Что вы, вероятно, считаете странным, так это рефлексивные отношения belongs_to, которые я пытаюсь смоделировать.Мой план состоит в том, что, в конце концов, Foo будет иметь много экземпляров Bar, в то время как один экземпляр будет считаться "активным".Таким образом, я использую active_bar для ссылки на этот активный экземпляр.Проблема с этим кодом заключается в том, что мне нужно установить свойство foo в Bar обратно на родительский экземпляр Foo, и я не могу найти лучшее место для этого (вызов save! в before_create заканчивает тем, что становится рекурсивным и переполняет стек) или даже если это самый чистый способ для моделирования этого типа отношений.

По сути, я пытаюсь смоделировать пользователя (эквивалент Foo), который имеетадреса электронной почты (эквивалентные Bar) с одним из адресов электронной почты, помеченных как основной адрес пользователя.

Любой совет?

1 Ответ

2 голосов
/ 16 июля 2010

Я просто собираюсь ответить с точки зрения User и EmailAddress, если это нормально с вами;)

В вашей пользовательской модели действительно должно быть has_many :email_addresses, has_one :active_email, :class_name => 'EmailAddress' и, как вы правильно определили, accepts_nested_attributes_for :email_addresses

Модель EmailAddress должна, конечно, иметь belongs_to :User.

Помимо этого, я думаю, что вы слишком обдумываете вещи. Затем в форме для создания пользователя разрешите ему вводить столько адресов электронной почты, сколько они захотят, и либо попросите их сначала указать свою «активную» электронную почту, либо используйте переключатель, чтобы указать, какой адрес электронной почты является их основным адресом.

Редактировать: Что касается оператора before_create, я думаю, что это просто должна быть простая проверка того, что основной адрес электронной почты был задан / отмечен (если необходимо, чтобы они указали адрес электронной почты в первую очередь).

Если это не соответствует необходимым функциям, пожалуйста, прокомментируйте. Я постараюсь помочь больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...