Rails belongs_to has_many具有自定义外键

时间:2013-06-01 19:32:24

标签: ruby-on-rails

我的rails应用程序中有两个模型之间的关系。我已经偏离了如何实现关系的标准,因为我使用另一个字段作为主键,命名约定是不同的。这样做导致这种关系似乎没有建立起来。我想了解原因。

这是我模特的精简版:

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

Player模型的字段alias是我的应用程序中的用户名。我希望用户名充当主键,因为它是唯一的,并且更容易迁移数据和维护关系。

最初我只有已填充数据的PlayerSession模型,但随着我的应用程序的增长,我添加了Player模型,只是插入了一行alias

Player的{​​{1}}视图中,我有以下代码:

show

当我尝试访问该页面时,它很简单,不显示信息。

我可以添加的其他信息是我没有在数据库本身中添加任何关系。

我还是铁杆新手,还在玩它。任何与编码标准有关的意见(在回答问题之外)都是受欢迎的。


更新我已通过在模型中添加Player Sessions: <% @player.player_sessions do |player_session| %> <ul> <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> </ul> 选项实施了Babur Usenakunov的建议:

primary_key

另外,为了测试数据是否有效,我手动获取了PlayerSession列表:

在控制器中实现的代码:

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

在视图中实现的代码(输出数据):

@player_sessions =  PlayerSession.where("player_alias = ?", params[:id])

2 个答案:

答案 0 :(得分:16)

我已经解决了这个问题,这是我在视图中实现的循环中添加each的问题:

<% @player.player_sessions.each do |player_session| %>
<ul>
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li>
</ul>    
<% end %>

在玩了一下之后,我意识到我不需要在任何一个视图中添加primary_key选项,只在Player模型中保留了外键选项。

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

答案 1 :(得分:2)

如果您的PlayerSession表有一个名为alias的列,那么您的外键也应该是alias,而不是player_alias。作为建议的标志,我要警惕使用别名作为foreign_key:如果您的播放器可以/决定更改其别名,那么数据库中的所有PlayerSession记录将变为无效并需要更新。使用诸如player_id之类的不可变参数将优于使用现有别名列IMHO。