Factory_bot: Factory not registered error depending on names of factory files

Created on 24 Aug 2012  路  2Comments  路  Source: thoughtbot/factory_bot

If I have a factory for HourlyViewCount and one of its fields is the ID for a VideoParticipant (created by a factory), FactoryGirl will give the error: Factory not registered: video_participant (ArgumentError)

However, if I take the name of the file hourly_view_count_factory.rb and rename it to zzhourly_view_count_factory.rb, FactoryGirl loads the dependent factory first and there is no problem. However, that solution isn't necessarily going to be very scalable if my factory dependencies get sufficiently complex.

Is there a better solution? I assume that if I require the dependent factory's file then I'll get an error later that the factory's already registered.

Most helpful comment

Can you paste the code? My guess is that your factory looks something like this:

# spec/factories/post.rb
FactoryGirl.define do
  factory :post do
    user_id FactoryGirl.create(:user).id
  end
end

# spec/factories/user.rb
FactoryGirl.define do
  factory :user
end

You'll want to evaluate the user_id at runtime, though, instead of when the factory file is read:

# spec/factories/post.rb
FactoryGirl.define do
  factory :post do
    user_id { FactoryGirl.create(:user).id }
  end
end

The result is twofold: first, it will now work (which is good!) and second, it'll get re-run every time you create the factory, which means it'll behave correctly (also good!). Let me know how it goes!

All 2 comments

Can you paste the code? My guess is that your factory looks something like this:

# spec/factories/post.rb
FactoryGirl.define do
  factory :post do
    user_id FactoryGirl.create(:user).id
  end
end

# spec/factories/user.rb
FactoryGirl.define do
  factory :user
end

You'll want to evaluate the user_id at runtime, though, instead of when the factory file is read:

# spec/factories/post.rb
FactoryGirl.define do
  factory :post do
    user_id { FactoryGirl.create(:user).id }
  end
end

The result is twofold: first, it will now work (which is good!) and second, it'll get re-run every time you create the factory, which means it'll behave correctly (also good!). Let me know how it goes!

You are indeed correct! I refactored my factory just slightly to use something like

FactoryGirl.define do
  factory :post do
    user FactoryGirl.create(:user)
  end
end

and that did still exhibit the issue, and sure enough, putting that as a block does make the factory behave correctly, which is great! And that explanation of when these things gets evaluated clears up a lot of odd behaviors I was seeing and getting confused about a few weeks back, so thanks!

Was this page helpful?
0 / 5 - 0 ratings