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 %>
They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.
In Ruby on Rails, a polymorphic association is an Active Record association that can connect a model to multiple other models. For example, we can use a single association to connect the Review model with the Event and Restaurant models, allowing us to connect a review with either an event or a restaurant.
Ruby on Rails ActiveRecord Associations has_oneA has_one association sets up a one-to-one connection with another model, but with different semantics. This association indicates that each instance of a model contains or possesses one instance of another model.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With