views:

46

answers:

1

I am a Rails newbie (from PHP). So forgive this basic data structures question:

In the controller:

@games = Game.all
@players = Player.all

In the view:

<% @games.each do |game| %>
  <%= game.player_id %>
<% end %>

When iterating over the @games, instead of displaying the player id with game.player_id, I'd like to display the player's name which can be found in the Player object (:name).

How do I 'find' the correct player record by the id stored in game.player_id?

+4  A: 

In the controller:

@games = Game.all(:include => :player)

In the view:

<% @games.each do |game| %>
  <%= game.player.name %>    
<% end %>

Your data model looks odd to me. For the similar problem my data model might look like this:

class Game < ActiveRecord::Base
  has_many :game_players
  has_many :players, :through => :game_players
end

class GamePlayer < ActiveRecord::Base
  belongs_to :game
  belongs_to :player
end

class Player < ActiveRecord::Base
  has_many :game_players
  has_many :games, :through => :game_players
end

Now in the controller I would query the games:

@games = Game.all(:include => :players)

In the view:

<%@games.each do |game| %>
  <% games.players.each do |player| %>
    <%= player.name %>
  <%end%>
<%end%>

Edit 1

If you have a concept of team then, I will introduce the team model:

class Player < ActiveRecord::Base
  has_many :team_players
  has_many :teams, :through => :team_players
end

class TeamPlayer < ActiveRecord::Base
  belongs_to :player
  belongs_to :team
end

class Team < ActiveRecord::Base
  has_many :team_players
  has_many :players, :through => :team_players
  belongs_to :game
  # attributes name, score team size constraints etc.
end

class Game
  has_many :teams
  has_many :players, :through => :teams.
end

Adding a new game:

@game = Game.new

@team_a = @game.teams.build(:name => "Foo")
@team_a.players << Player.find_all_by_name(["John", "Grace"])

@team_b = @game.teams.build((:name => "Bar")
@team_b.players << Player.find_all_by_name(["Kelly", "Yuvan"])

@game.save

While querying games in your controller:

@games = Game.all(:include => [{:teams => :players}])

In your view:

<%@games.each do |game| %>
  <% games.teams.each do |team| %>
    <% team.players.each do |team| %>
      <%= player.name %>
    <%end%>
  <%end%>
<%end%>
KandadaBoggu
Thank you for taking the time to look into my data model. How would you constrain the players to certain positions in the game? If it's a doubles tennis match, you have two players on each team playing against each other. The game would have a score for each team.
Etienne
Updated the answer, take a look.
KandadaBoggu
That's awesome. One last Rails related question. Considering that I have gone down the wrong path with my model and associated migrations, how does one redo stuff? Do I just create a new migration that fixes the schema to support new models or do I delete existing migrations and create new ones?
Etienne
If your tables does not have too much data, then you could simply drop and recreate your DB(i.e. `rake db:drop` followed by `rake db:create`) and then fix the migration files and run `rake db:migrate` again.
KandadaBoggu
Would this be the correct syntax for model creation: rails generate model GamePlayer game:reference player:reference ?
Etienne
Looks okay to me.
KandadaBoggu