Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何为相互验证的模型编写工厂?_Ruby On Rails_Ruby On Rails 4_Rspec_Factory Bot - Fatal编程技术网

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