factory_bot: Problems with factory_girl and has_many / belongs_to associations
Good morning everyone, Yesterday I started to use factory_girl with Rails. My setup features two classes with has_many / belongs_to relation between them. I literally followed the instructions for the has_many case here. My current code features this:
class User < ActiveRecord::Base
has_many :assistants, dependent: :destroy
end
class Assistant < ActiveRecord::Base
belongs_to :user
end
FactoryGirl.define do
factory :assistant do
name { Faker::Name.name }
user
end
factory :user do
name { Faker::Name.name }
email { Faker::Internet.email }
factory :user_with_assistants do
ignore do
assistants_count 5
end
after(:create) do |user, evaluator|
FactoryGirl.create_list(:assistant, evaluator.assistants_count, user: user)
end
end
end
end
My current problem is that the same kind of expression you use in the example does not work for me in the same way:
# I get this:
FactoryGirl.create(:user_with_assistants).assistants.length # => 0
I tried to dig a bit further and discovered the following:
# In Rails console
user = FactoryGirl.create(:user_with_assistants)
user.assistants.length # => 0
Assistant.where(user_id: user.id).all.length # => 5
As you can see, the list of assistants gets created correctly, but it is not available through the ActiveRecord association, and I need it to be available through the association to be able to test the relation between my two classes.
Obviously, I checked if the association works at all, and it does:
user = User.create(name: "Jony Ive", email: "jive@apple.com")
user.assistants.create(name: "Design Intern")
user.assistants.length # => 1
I will be very very thankful for any hints on what I am doing wrong.
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Reactions: 2
- Comments: 38 (3 by maintainers)
Commits related to this issue
- Improve documentation for collection associations This commit makes `Evaluator#association` and `Evaluator#instance` officially part of the public API of factory\_bot. Folks were already using these ... — committed to thoughtbot/factory_bot by composerinteralia 4 years ago
- Improve documentation for collection associations (#1420) * Improve documentation for collection associations This commit makes `Evaluator#association` and `Evaluator#instance` officially part of... — committed to thoughtbot/factory_bot by composerinteralia 4 years ago
I’m hesitant to add noise here, but I just wasted ~1 hour because of this issue. Perhaps, if nothing is done on the library side, the associations documentation could have a note added that mentions this behavior.
@appplemac if you put a
user.reload
in theafter(:create)
callback:Does that fix things?
@appplemac what happens is when the assistants get created, they associate themselves to the
user
butuser
doesn’t know about the changes to its internal state. Callinguser.reload
refreshes itself, pulling in newly created data that it didn’t know about before (in this case, the assistants).+1, this is really annoying
+1
What about traits? Not sure on the internals of this vs the factory method, or how it differs, but we use this quite a bit:
Also have done traits this way:
What is the status of this issue? Was it fixed? According to the documentation, using create_list in after(:create) should properly update both ends of the has_many relation. However, using factory_girl (4.5.0) I can still experience the issue.
If current object runs save validations that depend on the relationship with its
has_many
objects, the workaround of callingreload
inafter(:create)
won’t work.