Ruby on rails 如何为相互验证的模型编写工厂?
父类:Ruby on rails 如何为相互验证的模型编写工厂?,ruby-on-rails,ruby-on-rails-4,rspec,factory-bot,Ruby On Rails,Ruby On Rails 4,Rspec,Factory Bot,父类: class Parent < ActiveRecord::Base has_many :kids validates_presence_of :kids end 此配置导致无限循环。我尝试了FactoryGirl.build、FactoryGirl.create、after(:build)、before(:create)、关联、构建第二个虚拟工厂等的各种组合 写这些工厂最好的方法是什么?我犯了愚蠢的错误吗 似乎其他人也经历过这个问题: Ruby 2.2.1、Rails 4
class Parent < ActiveRecord::Base
has_many :kids
validates_presence_of :kids
end
此配置导致无限循环。我尝试了FactoryGirl.build、FactoryGirl.create、after(:build)、before(:create)、关联、构建第二个虚拟工厂等的各种组合
写这些工厂最好的方法是什么?我犯了愚蠢的错误吗
似乎其他人也经历过这个问题:
Ruby 2.2.1、Rails 4.1.5、rspec Rails 3.0.2、factory\u girl\u Rails 4.4.1。您发布的页面的答案实际上相当不错,因此我在这里引用它 你实际上不能那样做。使用挂钩的建议也很有限 如果需要在对象具有的位置构建对象层次结构 验证规则相互冲突,您将遇到以下相反的 该问题属于协会 ActiveRecord通常能够保存对象层次结构 如果它完全在内存中构建,然后通过 最高的祖先。在某些情况下,可以通过以下方式模拟此行为: 在工厂内使用Factory.build并添加after_build钩子 用于设置从属对象的定义。这对我来说不太好 层次结构的多个级别 最后一种方法是设置自己的助手方法和构造 内存中的对象层次结构,分配依赖项,然后调用save 在最上面的父级上。它不像工厂调用那样优雅, 但是,它可以帮助消除一堆设置代码的混乱 解决工厂和ActiveRecord的怪癖
对于我的用例,这是有效的: 母厂:
FactoryGirl.define do
factory :parent do
2.times do
parent.kids << FactoryGirl.create(:kid)
end
end
end
FactoryGirl.define do
factory :parent do
2.times do
parent.kids << FactoryGirl.create(:kid)
end
end
end
这个模式只是将一个新的、未使用的所有者对象分配给Kid工厂(以通过验证)。因为父母有很多孩子,孩子可以有很多父母,所以打电话给任何一家工厂都没有冲突。在规格中,可以覆盖默认关联以测试所需的行为
实际上,如果其中一个模型没有经过很多测试,你也可以不为其中一个模型创建工厂;您必须为每个规范创建模型的“新”实例,如果这是一个常见的情况,这并不理想
希望这能帮助别人 在创建时验证存在性几乎总是不是您想要的,因为它会在UI和控制器上强制执行人工约束。添加一个已验证的_at字段,并根据设置的条件进行状态检查。那么FactoryGirl就不会有这个问题了。谢谢@Gene,但这种双重验证模式实际上非常适合我的用例(主要是非UI逻辑)。谢谢@Elyasin,但我认为这些解决方案会带来更多的麻烦。我发布了我的解决方案,但我想看看你会使用什么代码。
FactoryGirl.define do
factory :kid do
parent
end
end
FactoryGirl.define do
factory :parent do
2.times do
parent.kids << FactoryGirl.create(:kid)
end
end
end
FactoryGirl.define do
factory :kid do
parent {Owner.new}
end
end