Hi there, I’m still new at this, but I’m creating a quick little
foosball stats app for my office(!) and I have a question about
relationships.
I have a table called games and a table called players. I’d like it so
when people enter information about a game they can choose from four
dropdowns the four players that played in the game.
At first I wasn’t thinking and thought it would be a basic thing like
this:
game.rb
has_many :players
and
player.rb
belongs_to :game
But then I couldn’t figure out how to link four players to one game.
Am I missing something really obvious? Is this a habtm instance?
Thanks!
Assuming that players play in more than one game and games have more
than one player, it is a has_and_belongs_to_many situation, yes.
The link that connects an instance of 4 players to a particular game
is called a Match. Different sports have different names for it, in
cricket it is a Test Match, in tennis it is a Match. So use the
terminology that is used in your foosball domain.
All the relevant data for that particular Match will go into that
table, for instance the stadium name, date of the game, whether the
Match was sold out etc. This is in addition to the foreign keys that
connect the other two classes.
You will have this association table with just the foreign keys if
your app does not need any other data mentioned above.
Consider a join table, using “has_many :through” constructs. This
allows you to record particulars of that players involvment in the game
(team, position, etc). I believe this is what Dave was suggesting with
the ‘match’ table, though match and game sound synonymous, and I’d use
someting to indicate involvement, like ‘encounters’ (derived from a
verb)
encounter.rb
belongs_to :player
belongs_to :game
player.rb
has_many :encounters
has_many :games, :through => encounters
game.rb
has_many :encounters
has_many :players, :through => encounters
See the rails docs on ‘has_many’, and Susser’s writings on
associations:
http://blog.hasmanythrough.com/articles/category/associations , for
more info.
If the application requires you to record details that relates the game
and
players in the encounter, then you can use has_many :through. Otherwise
habtm relationship will suffice.
Actually question leads to more important domain-designing issues:
- Are players on fixed teams? (this is easier, btw)
- How do you record wins?
For fixed teams, I would go with:
Class Players
#this assumes you can be on more than one team
have_and_belong_to_many :teams
Class Teams
have_and_belong_to_many :players
have_and_belong_to_many :matches
Class Matches
have_and_belong_to_many :teams
Then the Matches table migration would be:
t.column :team1_id, :integer, :null => false
t.column :team2_id, :integer, :null => false
t.column :winner_id, :integer, :null => false
t.column :team1_score, :integer, :null => false
t.column :team2_score, :integer, :null => false
t.column :played_at, :datetime, :null => false
#plus some foreign key mapping that I can’t be bothered to do
of course those should be ‘has_and_belongs_to_many’