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…)!

Comments