如何为模型编写相互验证的工厂?



父类:

class Parent < ActiveRecord::Base
  has_many :kids
  validates_presence_of :kids
end

小孩类:

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

孩子工厂:

FactoryGirl.define do
  factory :kid do
    parent
  end
end

此配置导致无限循环。FactoryGirl的每种组合我都试过了。构建、FactoryGirl。创建,在(: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, respect - Rails 3.0.2, factory_girl_rails 4.4.1.

你贴出的那一页的答案实际上很好,所以我在这里引用它。

你实际上不能那样做。使用钩子的建议也是有限的。

如果你需要构建对象层次结构,其中对象有验证规则相互对抗,您将遇到这个逆函数关于belongs_to关联的问题。

ActiveRecord通常能够保存对象层次结构如果它完全在内存中构造,然后通过最上层的祖先。在某些情况下,您可以通过使用工厂。在Factory中添加after_build钩子定义来设置依赖对象。这对于多于一个层次结构。

最后一种方法是设置自己的helper方法和构造对象层次结构,分配依赖项,然后调用save在最上面的双亲上。它不像Factory调用那样优雅,但它可以帮助整理一堆设置代码解决工厂和ActiveRecord的问题。

对于我的用例,这是有效的:

父工厂:

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

此模式只是将一个新的、未使用的所有者对象分配给Kid工厂(以通过验证)。因为Parent has_many Kids和Kid可以有许多Parents,所以调用这两个工厂时没有冲突。在您的规范中,您可以覆盖默认关联来测试所需的行为。

实际上,如果其中一个模型没有经过很多测试,你也可以不为其中一个模型创建工厂;您必须为每个规范创建模型的"新"实例,如果这种情况经常发生,这是不理想的。

希望这对某人有所帮助!

相关内容

  • 没有找到相关文章

最新更新