父类:
class Parent < ActiveRecord::Base
has_many :kids
validates_presence_of :kids
end
Kid Class:
class Kid < ActiveRecord::Base
belongs_to :parent, inverse_of: :kids
validates :parent, presence: true
end
家长工厂:
FactoryGirl.define do
factory :parent do
2.times do
parent.kids << FactoryGirl.create(:kid)
end
end
end
Kid Factory:
FactoryGirl.define do
factory :kid do
parent
end
end
此配置会导致无限循环。我已经尝试了FactoryGirl.build,FactoryGirl.create,(:build)之后,(:create),协会,建立第二个虚拟工厂等的每个组合。
写这些工厂的最佳方法是什么?我犯了一个愚蠢的错误吗?
似乎其他人也遇到过这个问题:http://www.rubyfocus.biz/blog/2010/12/18/factory_girl_association_hierarchies_inverse_of.html
Ruby 2.2.1,Rails 4.1.5,rspec-rails 3.0.2,factory_girl_rails 4.4.1。
答案 0 :(得分:0)
您发布的页面的答案实际上非常好,所以我在这里引用它。
你实际上不能这样做。并且使用钩子的建议也是有限的。
如果需要构建对象所具有的对象层次结构 相互验证规则,你会遇到这个逆向 与belongs_to协会有关。
ActiveRecord通常可以保存对象层次结构 正确的,如果它完全在内存中构建,然后通过保存 最顶级的祖先。您可以在某些情况下模拟此行为 使用Factory.build并在Factory中添加after_build挂钩 定义以设置依赖对象。这不适合 多层次的层次结构。
最后的方法是设置自己的帮助方法和构造 内存中的对象层次结构,分配依赖项,然后调用save 在最顶层的父母。它没有Factory调用那么优雅, 但它可以帮助解决一堆设置代码 解决工厂和ActiveRecord的怪癖。
答案 1 :(得分:0)
对于我的用例,这有效:
家长工厂:
FactoryGirl.define do
factory :parent do
2.times do
parent.kids << FactoryGirl.create(:kid)
end
end
end
Kid Factory:
FactoryGirl.define do
factory :kid do
parent {Owner.new}
end
end
此模式只是将一个新的未使用的所有者对象分配给Kid工厂(以传递验证)。由于父母has_many孩子和孩子可以有很多父母,所以在致电任何一家工厂时都没有冲突。在您的规范中,您可以覆盖默认关联以测试所需的行为。
实际上,如果其中一个模型没有经过大量测试,你也可以不为其中一个模型创建工厂;你必须为每个规范创建模型的“新”实例,如果这种情况很常见,这是不理想的。
希望能帮助别人!