Rails / ActiveRecord:has_one,belongs_to和before_create

时间:2010-07-16 18:03:03

标签: ruby-on-rails ruby activerecord

我无法确定如何最好地建模数据。我的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实例,我无法找到最佳位置({{ {1}} save!中的调用最终会被递归并溢出堆栈),或者即使这是建模此类关系的最简洁方法。

基本上我正在尝试为具有多个电子邮件地址(相当于before_create)的用户(相当于Foo)建模,其中一个电子邮件地址标记为用户的主要地址。

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

我只是想用User和EmailAddress来回复,如果你没问题的话;)

在您的用户模型中,您应该has_many :email_addresseshas_one :active_email, :class_name => 'EmailAddress',并且正确识别accepts_nested_attributes_for :email_addresses

然后,EmailAddress模型应具有belongs_to :User

除此之外,我认为你过分思考。在创建用户的表单中,允许他们输入任意数量的电子邮件地址,并让他们首先放置“活动”电子邮件,或者使用某种切换来表示哪个电子邮件地址是他们的主要地址。 / p>

编辑:就before_create语句而言,我认为只需要一个简单的验证即已给出/标记了主要电子邮件地址(如果首先必须指定电子邮件地址)。 / p>

如果这不能满足您的需求,请发表评论。我会尝试提供更多帮助。