Make FactoryGirl Respect Uniqueness When Creating Associations

If you have an ActiveRecord model associated with another model that has a uniqueness constraint, modeling it in FactoryGirl when writing specs doesn’t work out of the box. But there is a simple solution.

Let’s say you have a UserType ActiveRecord model which has a value field, with a unique constraint. Which means that in your DB you don’t have two records in user_types table with the same value field. You would have entries with value being admin, guest, student, teacher, etc. Now in your specs you want to declare a factory for each UserType. So using FactoryGirl, you are going to write something like this:

So far so good. You also decide to define factories for each kind of user:

Now somewhere in your spec you create two different guest users:

Of course you expect each guest object to be associated with the same UserType object. Let’s check:

And here is the surprise: each guest is associated with a different UserType object, one with id=1 and another with id=2. This is certainly not what we expected, so what’s going on?

Turns out that every time you call create(:my_factory), FactoryGirl creates a new object for every association that my_factory has. And that’s a problem if you expect every guest to be associated with the same UserType object. So what do we do?

The solution is simple: FactoryGirl allows you to initialize your factories in way that would respect uniqueness. Let’s revisit our UserType factories:

Using initialize_with we initialize each new guest user object with the same user_type we created previously. Let’s try to create two guests again and see if anything changed:

Great, we see that now each user is indeed associated with the same guest user_type record which has id=1.

And now, feel free to go and make yourself a cup of coffee, you earned it.

Leave a Reply

Your email address will not be published. Required fields are marked *