Forum: Ruby on Rails Need help configuring this data model

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5ac3a32ce9d0d638bef5d8009f18d621?d=identicon&s=25 Brad A (Guest)
on 2009-03-28 09:24
(Received via mailing list)
Consider 2 tables:
Player-> column player_id
and
Hit-> columns player_id, hit_player_id

I want one model for Player and one model for a Hit.
Any player has many hits against another player.
So from a Player I want to be able to get all the Hits, and from the
Hit get the hit Player.
On the other hand, from a Player I want to retrieve all Hits against
that player (were player_id = hits.hit_player_id)
and the player_id from that hit.

So far I have:

class Player < ActiveRecord::Base
    has_many :hits
end

and

class Hit < ActiveRecord::Base
    belongs_to :player
end

But I can't figure out how to map the 'hit' player.

Thanks for the help!
6883e5ef03484d4fcef507d7b4f1d243?d=identicon&s=25 Matt Jones (Guest)
on 2009-03-28 17:14
(Received via mailing list)
A quick note first - Player most likely shouldn't have a player_id
column - the Rails convention is to simply call it id.

What you're looking for are some of the options to has_many:

class Player < ActiveRecord::Base
  has_many :outgoing_hits, :class_name => 'Hit', :foreign_key =>
'hitter_id'
  has_many :incoming_hits, :class_name => 'Hit', :foreign_key =>
'hittee_id'

  has_many :hittees, :through => :outgoing_hits
  has_many :hitters, :through => :incoming_hits
end

class Hit < ActiveRecord::Base
  belongs_to :hitter, :class_name => 'Player'
  belongs_to :hittee, :class_name => 'Player'
end

Given a Player object, this is what you can do:

player.outgoing_hits # => list of hits by the player
player.incoming_hits # => list of hits to the player
player.hittees # => list of all players hit by this player
player.hitters # => list of all players hitting this player

You can switch the names around, but that's the idea.

--Matt Jones
5ac3a32ce9d0d638bef5d8009f18d621?d=identicon&s=25 Brad A (Guest)
on 2009-03-28 18:07
(Received via mailing list)
Thanks very much, I will give that a try.  Yes I did have the column
for player_id as "id", I mis-typed that, but its a good reminder,
appreciated.

-Brad
5ac3a32ce9d0d638bef5d8009f18d621?d=identicon&s=25 Brad A (Guest)
on 2009-03-29 01:55
(Received via mailing list)
This approach doesn't seem to be working for me.

I've set up the models as described above.
class Player < ActiveRecord::Base
  has_many :outgoing_hits, :class_name => 'Hit', :foreign_key =>
'player_id'
  has_many :incoming_hits, :class_name => 'Hit', :foreign_key =>
'hit_player_id'

  has_many :hittees, :through => :outgoing_hits
  has_many :hitters, :through => :incoming_hits
end

class Tag < ActiveRecord::Base
  belongs_to :hitter, :class_name => 'Player'
  belongs_to :hittee, :class_name => 'Player'
end

For player foo, I'm trying to list all the name of all players hit.
<ul>
<% @player.outgoing_hits.each do |hit| %>
<li><%=hit.hittee.screen_name%></li>
<%end%>
</ul>

But, "hittee" is null, although I can access other properties of the
hit.

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.screen_name

Here's the key columns of the 2 tables involved:
Player{
 id:integer
 screen_name:varchar
}

Hit{
  id:integer
  player_id:integer
  hit_player_id:integer
}
C8331af7b049b23f41664ff4b2675f07?d=identicon&s=25 vesan (Guest)
on 2009-03-29 11:09
(Received via mailing list)
Your associations and table columns don't match. You have to tell
Rails how to map hitter and hittee if you are not following
convention. By default foreign key for a belongs_to association is the
name of the association with an "_id" suffix.

So if you want to follow convention, you change Hit-table to be like
this:

Hit {
   id:integer
   hitter_id:integer
   hittee_id:integer
}

and change Player-class to use those column names (like in Matt Jones'
example).
5ac3a32ce9d0d638bef5d8009f18d621?d=identicon&s=25 Brad A (Guest)
on 2009-03-29 23:14
(Received via mailing list)
Correcting the column names did the trick.  Is there a similar
mechanism to the foreign-key hnit that can be used?  I thought there
used to be an identified-by keyword?
This topic is locked and can not be replied to.