Random Notes on Factory Girl Part II
More random/tutorialish aspects of my usage of the FactoryGirl gem. I do advise you to read their getting started guide, it helps a lot. This is more of a reference of the things I found most useful. If you have any questions/corrections/observations, let me know in the comments.
FactoryGirl and Polymorphic named associations
If you have polymorphic associations with different names, here’s how to go about it in factories:
factory :category, aliases: [:category_one, :category_two]
There are other approaches to this problem here, but I find this one to be the simplest and so far it hasn’t gotten me into trouble (perhaps yet :-) ).
Attributes_for
This is probably very obvious, but I find it useful to use attributes_for from FactoryGirl to build the valid attributes for use in controller specs.
def valid_attributes
FactoryGirl.attributes_for(:my_model)
end
One thing that is useful to know is that attributes_for ignores associations, and thus does not include attributes that are related to associations even if you have an association in the factory. Here is a post at stackoverflow that provides you with the foreign keys in the attributes if you need them.
Has_and_belongs_to_many associations
I’m just adding this for my own reference. It’s in the FactoryGirl getting started wiki.
FactoryGirl.define do
factory :person do
first_name { 'James' }
books {
Array(5..10).sample.times.map do
FactoryGirl.create(:book) # optionally add traits: FactoryGirl.create(:book, :book_description)
end
}
end
end
There is more in FactoryGirl associations here.
DRYing up: Traits
I just discovered traits, which are ways to add state to a factory (read: create factories whose attributes have different values without having to go through aliases). I am shamelessly copying Thoughtbot’s example because I think it’s the clearest one to have here for your reference:
FactoryGirl.define do
factory :todo_item do
name 'Pick up a gallon of milk'
trait :completed do
complete true
end
trait :not_completed do
complete false
end
end
end
DRYing up: inheritance
Something that I wasn’t making much use of – you can nest factories, which allows you to create multiple factories for the same class without repeating common attributes:
factory :user do
name "testing"
factory :super_user do
super_powers true
end
end
Tracking factories
I followed the advice here to track factories. I think it’s useful to know how factories are being used.
If you want to go really in depth…
You have a very nice post on code reading of the factorygirl gem here. You can even learn something about how to do cool stuff in ruby/rails like:
def set(attribute, value)
@instance.send(:"#{attribute}=", value)
end
And that’s all, folks (for now…)!