Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FactoryGirl, has_one association and validation failed

These are 2 simple models:

class Post < ActiveRecord::Base
  has_one :asset, :dependent => :destroy

  validates :asset, presence: true
end

class Asset < ActiveRecord::Base
  belongs_to :post
end

I'm trying to create a factory like this:

  factory :post do
    # fields...

    asset { FactoryGirl.create(:asset) }
  end

  factory :asset do
    # fields...

    post
  end

But, running the spec it enters a loop.

I've also tryied this:

  factory :post do
    # fields...

    before(:create) do |post, evaluator|
      FactoryGirl.create_list(:asset, 1, post: post)
    end
  end

But ended up in "Validation failed: Asset can't be blank".

How do I represent my situation?

like image 522
Mich Dart Avatar asked Jun 10 '13 23:06

Mich Dart


2 Answers

I solved this problem using after(:build) callback.

factory :post do
    # fields...
    after(:build) do |post|
      post.asset ||= FactoryGirl.build(:asset, :post => post)
    end
end

factory :asset do
    # fields...
    after(:build) do |asset|
      asset.post ||= FactoryGirl.build(:post, :asset => asset)
    end
end

By this way, the associated objects will be created before the owning class is saved, so validation pass.

like image 63
Mich Dart Avatar answered Oct 31 '22 01:10

Mich Dart


The validation is failing because when FactoryGirl creates a Post, an asset must be present. So in your FactoryGirl definitions you can create an Asset as part of creating a Post. Insert something like the FactoryGirl post.rb file:

asset { FactoryGirl.create(:asset) }

or

You can create an Asset as part of your Post declaration in your spec file such as the following:

asset = FactoryGirl.create(:asset)

FactoryGirl.create(:post, :asset => asset)

Thanks.

like image 39
Iz103 Avatar answered Oct 31 '22 00:10

Iz103