user10569544
user10569544

Reputation: 13

ActiveRecord belongs_to association id is not always set

I have models like this:

class Member
  belongs_to :team, class_name: 'Team'
end

class Team
  has_many :members, foreign_key: :team_id
end

Database has all the columns needed.

When I do: t = Team.new m = Member.new

m.team = team
m.save!
#some other code
t.save!

team_id field is present most of the times but is absent sometimes in the database. I saw in active record documentation that belongs to association is not saved. This looks like a race condition to me but I want to understand why it might happen.

Thanks in advance!

Upvotes: 1

Views: 1885

Answers (1)

anothermh
anothermh

Reputation: 10564

Always create associated objects through the association. That means that you should do the following:

t = Team.create!
m = t.members.create!

This is described in greater detail in the guide for Active Record Associations.

You asked why the example you provided works sometimes but not others. I cannot replicate the problems that you're seeing. It is probably something specific to your implementation or practices that are not shared in your question. Here is how I verified that the issue does not occur.

First, create the Rails app, its associations, its database, and then start the Rails console:

rails new tester
cd tester
rails generate model Team
rails generate model Member team:belongs_to
sed -i '' 's/end/  has_many :members\'$'\nend/' app/models/team.rb
rake db:migrate
rails console

Now create one thousand teams with an associated member, and if the fields are not appropriately set then raise an exception:

1000.times do
  t = Team.create!
  m = t.members.create!
  raise unless m.team_id && m.team_id == t.id
end

Or alternatively, using .new and .save!:

1000.times do
  t = Team.new
  m = t.members.new
  m.save!
  raise unless m.team_id && m.team_id == t.id
end

No exception is raised, so by creating in this manner you can be assured that it will work properly.

Upvotes: 3

Related Questions