Reputation: 12621
I have a relationship between 2 models in my rails application. I have veered away from the standard of how to implement the relationship as I used another field as a primary key and the naming convention is different. Doing so resulted in the relationship seemingly not being established. I want to understand as to why.
This is a trimmed down version of my models:
class Player < ActiveRecord::Base
set_primary_key "alias"
attr_accessible :alias, :avatar
has_many :player_sessions, :foreign_key => "player_alias", :class_name => "PlayerSession"
end
class PlayerSession < ActiveRecord::Base
attr_accessible :player_alias, :total_score
belongs_to :player, :foreign_key => "player_alias", :class_name => "Player"
end
The Player
model has the field alias
which is the username in my application. I wanted the username to act as the primary key since it is unique and it would be easier to migrate the data and maintain relationships.
Originally I only had PlayerSession model with data already filled in, but as my application grew I added the Player model and simply inserted a row with the same alias
.
In the Player
's show
view I have the following code:
Player Sessions:
<% @player.player_sessions do |player_session| %>
<ul>
<li><h4>Highest Score:</h4> <%= player_session.total_score %> </li>
</ul>
When I try to access the page it simple doesn't show the information.
Other information I can add is that I haven't added any relationships in the database itself.
I am still new to rails and still playing around with it. Any opinions that concern coding standards(outside from answering the question) are welcome.
Update I have implemented Babur Usenakunov's suggestion by adding the primary_key
option in the models:
class Player < ActiveRecord::Base
set_primary_key "alias"
attr_accessible :alias, :avatar
has_many :player_sessions, :primary_key => "alias", :foreign_key => "player_alias", :class_name => "PlayerSession"
end
class PlayerSession < ActiveRecord::Base
attr_accessible :player_alias, :total_score
belongs_to :player, :primary_key => "alias", :foreign_key => "player_alias", :class_name => "Player"
end
Also to test out the the data is valid I acquired the PlayerSession list manually:
Code implemented in controller:
@player_sessions = PlayerSession.where("player_alias = ?", params[:id])
Code implemented in view(which outputs the data):
<% @player_sessions.each do |player_session| %>
<ul>
<li><h4>Highest Score:</h4> <%= player_session.total_score %> </li>
</ul>
<% end %>
Upvotes: 33
Views: 49384
Reputation: 12621
I have solved the issue, it was a matter of adding each
in the loop I implemented in the view:
<% @player.player_sessions.each do |player_session| %>
<ul>
<li><h4>Highest Score:</h4> <%= player_session.total_score %> </li>
</ul>
<% end %>
After playing around a bit, I realised i didn't need to add the primary_key option in either of the views, and left the foreign key option only in the Player
model.
class Player < ActiveRecord::Base
set_primary_key "alias"
attr_accessible :alias, :avatar
has_many :player_sessions, :foreign_key => "player_alias", :class_name => "PlayerSession"
end
class PlayerSession < ActiveRecord::Base
attr_accessible :player_alias, :total_score
belongs_to :player, :class_name => "Player"
end
Upvotes: 28
Reputation: 265
If your PlayerSession table has a column named alias
then your foreign key should also be alias
, not player_alias
. As a token of advice I'd be wary of using an alias as a foreign_key: if your player can/decide to change his alias then all PlayerSession records within your database will become invalid and require an update. Using an immutable parameter such as player_id
would be preferable to using the existing alias column IMHO.
Upvotes: 3