Kamilski81
Kamilski81

Reputation: 15117

How can I populate a join (many-to-many) table inside seeds.rb for ruby on rails?

I currently have a model for team.rb and user.rb, which is a many to many relationship. I have created the join table teams_users but I am not sure how to populate this table in my seeds.rb?

For example, I have :

user = User.create({ first_name: 'Kamil', last_name: 'Bo', email: '[email protected]'})
team = Team.create([{ name: 'Spot Forwards', num_of_games: 10, day_of_play: 4}])

But the following does not work???

TeamsUsers.create({ team_id: team.id, user_id: user.id })

I get a message :

uninitialized constant TeamsUsers

Upvotes: 1

Views: 4577

Answers (3)

Kevin Hutchinson
Kevin Hutchinson

Reputation: 2373

Using Rails, say you have tables foos and bars in a many-to-many relationship using table foos_bars, you can seed their associations like this:

bar1 = Bar.find(1)
bar2 = Bar.find(2)

foo1 = Foo.find(1) # for example
foo1.bars << bar1
foo1.bars << bar2
foo1.save

This will update the joins table foos_bars with associations <foo_id:1, bar_id:1>, <foo_id:1, bar_id:2>

Hope this helps.

Upvotes: 1

partydrone
partydrone

Reputation: 537

Pick a side to work from and then, as @drhenner suggests, use the _ids property to create the association. For example, working with the User model, create the teams first, then the users, assigning them to teams as you go:

teams = Team.create([
  { name: 'Team 1' },
  { name: 'Team 2' },
  { name: 'Team 3' },

  # etc.
])

User.create([
  { name: 'User 1', team_ids: [teams[0].id, teams[2].id] },
  { name: 'User 2', team_ids: [teams[1].id, teams[2].id] },
  { name: 'User 3', team_ids: [teams[0].id, teams[1].id] },

  # etc.
])

From comment above:

You can have multiple relationships configured on a has_many :through relationship. It's up to you which ones you want to implement. These are all the possibilities:

class Team < ApplicationRecord
  has_many :memberships
  has_many :users, through: :memberships
end

class Membership < ApplicationRecord
  belongs_to :team
  belongs_to :user
end

class User < ApplicationRecord
  has_many :memberships
  has_many :teams, through: :memberships
end

So, when dealing with the Team model, you can use: team.memberships and team.users;

when dealing with the User model, you can use: user.memberships and user.teams;

and if dealing with the join model, you can use: membership.team and membership.user.


You can omit the relationship references to the join model if you don't use it—especially if you're treating the relationship between Team and User like a standard has_and_belongs_to_many relationship:

class Team < ApplicationRecord
  has_many :users, through: :memberships
end

class User < ApplicationRecord
  has_many :teams, through: :memberships
end

This gives you team.users and user.teams.

Upvotes: 1

drhenner
drhenner

Reputation: 2230

This isn't optimized but

user.team_ids = user.team_ids < team.id
user.save

or if this is the first team

user.team_ids = [team.id]
user.save

ALso start using has_many :through. then you will have a TeamUser model. it's a life saver if the join table needs more attributes

Upvotes: 2

Related Questions