How to specify traits for model associations in FactoryGirl
If you’re using RSpec and FactoryGirl to automate testing for your Rails app, you probably know that when creating a factory for a model that has association you can simply specify the factory of the associated model. For example, suppose your Contact model has associations with Phone and Store models:
FactoryGirl.define do factory :contact do | f | f.name { Faker::Name.name } phone store end end |
And you probably know you can have traits for factories, for example, different settings for different types of stores:
FactoryGirl.define do
factory :store do |f|
after(:create) { |store|
store.update_attributes :name => Faker::Name.last_name + " LLC"
}
trait :unknown do
after(:build) { |store| store.init_blank(Settings.feature_set_unknown) }
end
trait :restaurant do
after(:build) { |store| store.init_blank(Settings.feature_set_restaurant) }
end
trait :retailer do
after(:build) { |store| store.init_blank(Settings.feature_set_retailer) }
end
end
end
However, what we could not find documented anywhere was how to specify a trait for an associations. Say when you create a contact factory you want specify which type of store that contact belongs to:
Here’s the magic decoder ring… use
:factory => [:association_factory_name, :trait_name]
FactoryGirl.define do
factory :contact do |f|
f.name { Faker::Name.name }
phone association :store, :factory => [:store, :unknown]
trait :foodie_contact do
association :store, :factory => [:store, :restaurant]
end
trait :retailer_contact do
association :store, :factory => [:store, :retailer]
end
end
end
Which you can then invoke as follows in your examples:
c = FactoryGirl.create(:contact, :retailer_contact)