Search code examples
ruby-on-railsfactory-botmodel-associations

Improving factories of associated models


I have three models : User, Product and Ownership. Ownership belongs to User and Product. Product and User have many Ownerships.

I created the following factories with the FactoryGirl gem :

factory :user do
  sequence(:name)  { |n| "Robot #{n}" }
  sequence(:email) { |n| "numero#{n}@robots.com"}
  association :location, factory: :location
end

factory :product do
  sequence(:name) { |n| "Objet #{n}" }
  association :location, factory: :location
end

factory :ownership do
  association :user, factory: :user
  association :product, factory: :product
end

And I use it like that :

let(:user) { FactoryGirl.create(:user) }
let(:product) { FactoryGirl.create(:product) }
let(:ownership) { FactoryGirl.create(:current_ownership, user: user, product: product) }

But I want to improve my factories, in order to do this :

let(:user) { FactoryGirl.create(:user) }
let(:product) { FactoryGirl.create(:product, owner: user) }

Do you have any idea how to do that ?


Solution

  • You can do this using the factory girl after_create callback:

    FactoryGirl.define do
      factory :product do
        # ...
    
        ignore do
          owner nil
        end
    
        after :create do |product, ev|
          if ev.owner
            create :ownership, user: ev.owner, product: product
          end
        end
      end
    end
    

    This way you configure factory so, that you can pass owner attribute into it. The ignore block ensures this attribute won't be passed to the object's constructor, but you can use it in the factory girl's callbacks.

    You can find more information on factory girl callbacks here.