home icon contact icon rss icon

By: Matt Lins

Factory_Girl Sequences as Lazy Attributes

I just ran into a problem with factory_girl sequences. The problem was I defined my Factories like this:

1
2
3
4
5
6
7
8
9
10
11
12
# Sequences

Factory.sequence :name do |n|
  'name' + n.to_s
end

# Manufacturers

Factory.define :manufacturer do |m|
  m.name Factory.next(:name)
  m.active true
end

Assume I have a validates_uniqueness_of validation on name in Manufacturer:

1
2
3
4
5
class Manufacturer < ActiveRecord::Base

  validates_uniqueness_of :name

end

Now, lets say I created a couple of manufacturers in my test setup:

1
2
3
4
5
6
7
8
9
require File.dirname(__FILE__) + '/../test_helper'

class ProductTest < ActiveSupport::TestCase

  setup do
    2.times { Factory(:manufactuer) }
  end

end

Ok, this setup block will fail because it's creating 2 manufacturers with the same name. But, I thought I was using a sequence? Well, the sequence is only sequenced during the definition of the factories. Meaning, in the above example Factory#next was only called once.

Luckily, factory_girl allows us to use something called lazy attributes. We can just wrap our sequence with some curly brackets, like so:


m.name { Factory.next(:name) }

Now everytime I create a new Manufacturer the sequence will generate a unique name. Nice! Maybe if I'd taken some more time to RTFM, I wouldn't have wasted time on this problem. Regardless, I thought maybe I'd be able to help someone else out that runs into this.

More about factory_girl

jason said

Dec 19, 2008 @ 02:12 AM

Thanks, it helped me, I missed it too. I think the docs aren't clear enough about this though.

Matt Van Horn said

Jul 12, 2009 @ 07:13 AM

Thanks, it got me too.