Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bypass Rails validations when creating FactoryGirl objects

I have two models (ModelA and ModelB), and FactoryGirl factories for each. I want the factory for ModelB to be able to (A) create test data, and to (B) build (without saving to database) sample data for display to customers. I am having trouble getting (A) to work due to Rails validations in my models.

ModelA:

class ModelA < ActiveRecord::Base   belongs_to :model_b   validates_presence_of :model_b end 

Factory for ModelA:

FactoryGirl.define do   factory :model_a do     some_attr "hello"     model_b { FactoryGirl.build :model_b }   end end 

ModelB

class ModelB < ActiveRecord::Base   has_one :model_a end 

Factory for ModelB

FactoryGirl.define do   factory :model_b do     some_attr "goodbye"   end end 

I can't create objects from these factories without getting validation errors:

 ruby> FactoryGirl.create :model_a  ActiveRecord::RecordInvalid: Validation failed: ModelB can't be blank 

It appears that FactoryGirl is attempting to save the factory object before saving its assocations. I realize that I could have the factory for ModelB create its associated ModelA (rather than build it) - however, then I would lose the flexibility of being able to use the ModelA factory to either build sample data or save test data. Alternately, I could remove the validations; but then I wouldn't have validations.

Any other options?

like image 861
maxenglander Avatar asked Oct 04 '11 19:10

maxenglander


2 Answers

How about this?

FactoryGirl.build(:model_a).save(validate: false) 

EDIT: As Scott McMillin comments below, if you want the built object as a variable, you can to do this:

model_a = FactoryGirl.build(:model_a) model_a.save(validate: false) 
like image 64
Houen Avatar answered Sep 19 '22 14:09

Houen


I looked into a couple solutions.

One is to create a custom proxy, illustrated here: http://codetunes.com/2009/11/05/fixtures-without-validation-with-factory-girl

The other is to set a to_create block in the factory:

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 
like image 43
maxenglander Avatar answered Sep 22 '22 14:09

maxenglander