[英]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
来引用此活动实例。 这段代码的问题是,我需要将Bar
的foo
属性设置回父Foo
实例,并且我无法找出执行此操作的最佳位置( before_create
的save!
调用最终是递归的,并且溢出了堆栈),即使这是对这种类型的关系进行建模的最简洁的方法。
本质上,我正在尝试为具有多个电子邮件地址(相当于Bar
)的用户(相当于Foo
)建模,并将其中一个电子邮件地址标记为用户的主要地址。
有什么建议?
如果您可以的话,我将就用户名和电子邮件地址做出回应;)
在您的用户模型中,实际上应该是has_many :email_addresses
, has_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.