创建FactoryGirl对象时绕过Rails验证

max*_*der 25 ruby-on-rails factory-bot

我有两个模型(ModelA和ModelB),每个都有FactoryGirl工厂.我希望ModelB的工厂能够(A)创建测试数据,并且(B)构建(不保存到数据库)样本数据以显示给客户.由于我的模型中的Rails验证,我无法让(A)工作.

MODELA:

class ModelA < ActiveRecord::Base
  belongs_to :model_b
  validates_presence_of :model_b
end
Run Code Online (Sandbox Code Playgroud)

ModelA工厂:

FactoryGirl.define do
  factory :model_a do
    some_attr "hello"
    model_b { FactoryGirl.build :model_b }
  end
end
Run Code Online (Sandbox Code Playgroud)

ModelB

class ModelB < ActiveRecord::Base
  has_one :model_a
end
Run Code Online (Sandbox Code Playgroud)

ModelB的工厂

FactoryGirl.define do
  factory :model_b do
    some_attr "goodbye"
  end
end
Run Code Online (Sandbox Code Playgroud)

如果没有验证错误,我无法从这些工厂创建对象:

 ruby> FactoryGirl.create :model_a
 ActiveRecord::RecordInvalid: Validation failed: ModelB can't be blank
Run Code Online (Sandbox Code Playgroud)

似乎FactoryGirl在保存其关联之前尝试保存工厂对象.我意识到我可以让ModelB的工厂创建其关联的ModelA(而不是构建它) - 然而,我将失去能够使用ModelA工厂来构建样本数据或保存测试数据的灵活性.或者,我可以删除验证; 但后来我没有验证.

还有其他选择吗?

Hou*_*uen 26

这个怎么样?

FactoryGirl.build(:model_a).save(validate: false)
Run Code Online (Sandbox Code Playgroud)

编辑:正如Scott McMillin在下面评论的那样,如果你想将构建的对象作为变量,你可以这样做:

model_a = FactoryGirl.build(:model_a)
model_a.save(validate: false)
Run Code Online (Sandbox Code Playgroud)


max*_*der 17

我找了几个解决方案.

一种是创建自定义代理,如下所示:http: //codetunes.com/2009/11/05/fixtures-without-validation-with-factory-girl

另一种是to_create在工厂设置一个块:

FactoryGirl.define do
  factory :model_a do
     model_b { FactoryGirl.build :model_b }       

     to_create do |instance|
       instance.model_b.save!
       instance.save!
     end 
  end
end
Run Code Online (Sandbox Code Playgroud)