Basically I am trying to work out how to go from my current applications
to actually useful ones where i can map objects onto other objects i.e.
a simple team planner
table teams
table players
So i want to create players and then be able to add as many players as i
want to a team, choosing the existing players. I have followed 2
tutorials and haven’t been able to apply them like this (one was a
really old one, so thats just a rails difference), can anyone spend 5
minutes explaining to me how to do this or point me to a really simple
tutorial that just explains this without extra cruft?
second method sounds perfect, problem being i just can’t seem to get the
code right… what exact relationships do i need in the tables? (foreign
keys? anything like that?) and what code in the m/v/c to set up the
relationship…
this basically adds a friendship model to your app in order to easily
make relationships between users.
maybe a good idea for your project.
however thinking about it, you’ll probably want some kind of table
relationship.
if your users will only belong to one team, then you could simply have
an extra field in your user table which can be set to the team_id of the
one they’re in.
if they can join as many teams as they want, then you could try…
//user:
user_id (1)
user_name (john)
//team_relationship:
user_id (2)
team_id (1)
//team:
team_id (1)
team_name (croatia)
the team relationship table is the glue that plugs the user table to the
team table.
the sql code shouldn’t be that hard to figure out, think inner joins.
Brilliant, dropping the team metaphor, lets say i wanted to record games
and players and scores, with each game having many players but each
player only 1 score (per game).
really old one, so thats just a rails difference), can anyone spend 5
minutes explaining to me how to do this or point me to a really simple
tutorial that just explains this without extra cruft?
A team has many players, and players belong to only one team. So in
your Team class, add this line:
has_many :players
and in your Player class add this line:
belongs_to :team
And in your players table, have an int column named team_id
That’s it. Rails will handle the relationship. You’ll now magically
have an array in Team called players.
To assign a player to a team, just write something like this:
team = Team.find_by_name(“Gorillas”) #for example
some_player.team = team
Brilliant, dropping the team metaphor, lets say i wanted to record
games
and players and scores, with each game having many players but each
player only 1 score (per game).
Now you’ve got a different relationship, because before players could
have only one team, but they can have many games and also belong to
many games.
So in Game you add
has_and_belongs_to_many :players
and in Player you add
has_and_belongs_to_many :games
For this type of relationship neither your games table nor your
players table gets a foreign key. (In the Teams-Players question the
players table had a team_id column).
So you have to create a third table to allow rails to manage the
relationship. The name of the table should be the two other tables in
alphabetical order, separated by an underscore.
So in this case, that table is named games_players, and contains a
game_id column and a player_id column.
Now a player magically has an array called games, and a game has an
array called players. To add a player to a game, write it like this:
some_game.players << this_player. Or you can do it the other way
around. It doesn’t matter, because what will happen is that rails will
add to that join table a row containing both IDs.
But this is just scratching the surface. There is much more you can do
with a HABTM relationship. Googling has_and_belongs_to_many will get
you a whole bunch of good articles.
Also, if you still have teams that part doesn’t change. A player can
both belongs_to :team and has_and_belongs_to_many :games.
Surely a good way to link players to games would be to create scores
that map to a player and a game… means lots of games with however many
players you want, each with 1 score per game. how should i be doing it?
Somewhere you ought to have something like @players = my_game.players.
Or, if you’ve already got an @game, just put @game.players in there.
Surely a good way to link players to games would be to create scores
that map to a player and a game… means lots of games with however
many
players you want, each with 1 score per game. how should i be doing
it?
I would think the score would be part of the definition of a game.
Just for an example, assuming a game had a score, and I wanted to find
a player’s average score, I could write
total = 0
my_player.games.each{ |game| total += game.score }
avg_score = total/my_player.games.size
(you might check for a size of zero before dividing, of course)