Reputation: 305
For example I have model Match and model Player. What I want is for Player to be able to participate in many matches.
So it should look smth like this:
@match_first = Match.first
@match_last = Match.last
@match_first.players
#player1, player3, player4
@match_last.players
#player1, player4, player5
Both matches can have same players simultanously.
Upvotes: 0
Views: 103
Reputation: 4126
Rails provides two ways to accomplish the many-to-many relationship. The first, which @zoot's answer describes, is has_many :through
. This is a great option if the relationship is a Model in its own right (i.e., needs additional attributes or validations).
If the relationship between the two entities is direct such that you don't really need a third model, you can use the has_and_belongs_to_many
association.
In your Match model:
has_and_belongs_to_many :players
In your Player model:
has_and_belongs_to_many :matches
When you use has_and_belongs_to_many
you do need to create a join table that holds the relationship. The migration for that (assuming a relatively recent version of Rails) might look like:
class CreateJoinTableMatchesPlayers < ActiveRecord::Migration
def change
create_join_table :matches_players, :users do |t|
t.index [:match_id, :player_id], unique: true
end
end
end
There's a section in the Active Record Associations guide that talks about how to choose between the two approaches.
Upvotes: 1
Reputation: 36
In your Match model:
has_many: :players, through: :appearances
In your Player model:
has_many: :matches, through: :appearances
class Appearance < ActiveRecord::Base
belongs_to :match
belongs_to :player
You could have extra attributes on appearance like 'goals_scored'. The through model doesn't have to be called Appearance... it could be Attendance or MatchPlayer or PlayerMatch, but you can see that the last two names are constraining, because out of this association you can also see all the matches a player appeared in.
Upvotes: 2