Michelle
Michelle

Reputation: 201

Accessing factory_girl factories in *other* factories

I'm using the factory_girl plugin in my rails application. For each model, I have a corresponding ruby file containing the factory data e.g.

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  # t.user ???
end

I have lots of different types of users (already defined in the user factory). If I try the following though:

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  t.user Factory(:valid_user) # Fails
end

I get the following error:

# No such factory: valid_user (ArgumentError)

The :valid_user is actually valid though - I can use it in my tests - just not in my factories. Is there any way I can use a factory defined in another file in here?

Upvotes: 20

Views: 6928

Answers (3)

OddballGreg
OddballGreg

Reputation: 21

Potentially a new feature to Factory Girl judging by the age of the question, but if the name of your attribute in the Factory is the same as the name of the factory, simply calling the name of the attribute in your factory will populate it with the associated Factory generation.

FactoryGirl.define do
   factory :thing do
     user
   end
end

This should result in the user field looking for a factory with the same name and populating it from that.

Upvotes: 2

Gdeglin
Gdeglin

Reputation: 12618

You should use this code:

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  t.user { Factory(:valid_user) }
end

Wrapping the call in {} causes Factory Girl to not evaluate the code inside of the braces until the :valid_thing factory is created. This will force it to wait until the :valid_user factory has been loaded (Your example is failing because it is not yet loaded), it will also cause a new :valid_user to be created for each :valid_thing rather than having the same user for all :valid_thing's (Which is probably what you want).

Upvotes: 32

Peter Brown
Peter Brown

Reputation: 51717

Try using the association method like:

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  t.association :valid_user
end

Upvotes: 4

Related Questions