打电话给定有一个Foo
和Bar
型号one-to-one
关系和彼此的存在验证:通知一到一个模型保存存在验证两侧
class Foo < ActiveRecord::Base
has_one :foo_bar
has_one :bar, through: :foo_bar, inverse_of: :foo
validates :bar, presence: true
end
class FooBar < ActiveRecord::Base
belongs_to :foo
belongs_to :bar
end
class Bar < ActiveRecord::Base
has_one :foo_bar
has_one :foo, through: :foo_bar, inverse_of: :bar
validates :foo, presence: true
end
和工厂为他们:
FactoryGirl.define do
factory :foo do
foo_bar
bar { |foo| build(:bar, foo_bar: foo_bar, foo: foo) }
end
factory :bar do
foo_bar
foo { |bar| build(:foo, foo_bar: foo_bar, bar: bar) }
end
factory :foo_bar do
end
end
当我尝试创建Foo
或Bar
与FactoryGirl.create(:foo)
的实例时,我得到SystemStackError: stack level too deep
。
这样做的原因是:
- 当保存
foo
对象看起来在相关bar
- A-HA!
bar
不会被保存,我们需要保存它首先 - 虽然节省
bar
它着眼于foo
(其中尚未保存)和 决定将其保存 - 等它试图挽救对方这会导致无穷环
一个解决方案是对关联的像的端部之一添加autosave: false
:
class Bar
has_one :foo, through: :foo_bar, inverse_of: :bar, autosave: false
end
这允许创建Foo
但PR事件create(:bar)
,因为foo
协会将不会被保存,这将导致无效的Bar
记录(由于验证)。
如何修复,以便foo
和bar
工厂都有效?
你能否解释为什么你会使用这种关系而不是'has_one'&'belongs_to'?使用一个额外的模型,而不是一个额外的领域似乎很复杂。 – 2015-02-08 11:33:34
@TheChamp这听起来很合理,但我仍然对解决原始问题感兴趣。 – freemanoid 2015-02-09 07:19:23