has_many association causing FactoryGirl beta to throw undefined local variable or method for FactoryGirl::SyntaxRunner

Factory Girl is powerful as heck, but it seems like some of the errors for has_many associations just come up as an error from FactoryGirl’s syntax runner. There are a bunch of different causes that come up from a few google searches, but here’s one that I hadn’t seen answered anywhere else. This could be caused by ruby 2.1, or by using the FactoryGirl beta 3.0.0, I’m not too sure.

I have an association:

to_do_item belongs_to to_do_list
to_do_list has_many to_do_items

I wanted a to_do_list factory that contained several to_do_items. You set this up with the after(:create)callback. For more information, see this excellent blog post from thoughtbot. My factory read like this:

FactoryGirl.define do
  factory :to_do_list do
  end

  factory :three_item_list, parent: :to_do_list do
    after(:create) do |list|
      to_do_items << FactoryGirl.create(:to_do_item, {content: "item one", to_do_list: list, created_at: (DateTime.now - 1.hour)})
      to_do_items << FactoryGirl.create(:to_do_item, {content: "item two", to_do_list: list, created_at: (DateTime.now - 1.day)})
      to_do_items << FactoryGirl.create(:to_do_item, {content: "item three", to_do_list: list, created_at: (DateTime.now)})
    end
  end
end

The factory itself passes a .valid? call, but trying to use it threw the SyntaxRunner exception. After reading and re-reading the FactoryGirl readme a bunch, on a whim I tried out:

FactoryGirl.define do
  factory :to_do_list do
  end

  factory :three_item_list, parent: :to_do_list do
    after(:create) do |list|
      list.to_do_items << FactoryGirl.create(:to_do_item, {content: "item one", to_do_list: list, created_at: (DateTime.now - 1.hour)})
      list.to_do_items << FactoryGirl.create(:to_do_item, {content: "item two", to_do_list: list, created_at: (DateTime.now - 1.day)})
      list.to_do_items << FactoryGirl.create(:to_do_item, {content: "item three", to_do_list: list, created_at: (DateTime.now)})
    end
  end
end

and my specs stopped throwing a SyntaxRunner exception and started failing as I’d expect them to. So there you go, it might be necessary in a has_many association to explicitly name the receiving object.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s