繁体   English   中英

Rails / ActiveRecord:has_one,belongs_to和before_create

[英]Rails/ActiveRecord: has_one, belongs_to and before_create

我在弄清楚如何最好地建模数据时遇到了麻烦。 我的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来引用此活动实例。 这段代码的问题是,我需要将Barfoo属性设置回父Foo实例,并且我无法找出执行此操作的最佳位置( before_createsave!调用最终是递归的,并且溢出了堆栈),即使这是对这种类型的关系进行建模的最简洁的方法。

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

有什么建议?

如果您可以的话,我将就用户名和电子邮件地址做出回应;)

在您的用户模型中,实际上应该是has_many :email_addresseshas_one :active_email, :class_name => 'EmailAddress'并且如您所正确识别的那样, accepts_nested_attributes_for :email_addresses

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

除了这些,我认为您正在考虑过多。 然后,在创建用户的表单中,允许他们输入所需数量的电子邮件地址,或者让他们首先放置“活动”电子邮件,或者进行某种形式的切换以指示哪个电子邮件地址是其主要地址。

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

如果这不能满足您所需的功能,请发表评论。 我会尽力帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM