【问题标题】:Rails belong_to has_many with a custom foreign key带有自定义外键的 Rails belongs_to has_many
【发布时间】:2013-05-28 09:46:04
【问题描述】:

我的 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 的行。

Playershow 视图中,我有以下代码:

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

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

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

我对 Rails 还很陌生,并且还在玩它。欢迎任何与编码标准有关的意见(除了回答问题)。


更新我已经通过在模型中添加 primary_key 选项来实施 Babur Usenakunov 的建议:

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

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

控制器中实现的代码:

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

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

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

【问题讨论】:

  • 我不确定,但也许您也应该在选项中传递主键。例如。 has_many :player_sessions, :primary_key =&gt; 'alias', :foreign_key =&gt; 'player_alias' :class_name =&gt; 'PlayerSession'belongs_to :player, :primary_key =&gt; 'alias', :foreign_key =&gt; "player_alias", :class_name =&gt; "Player"
  • 试过了还是不行
  • @Drahcir,我倾向于认为 Babur Usenakunov 的建议应该有效。 @player.player_sessions 在您尝试了他们的建议后返回了什么?
  • @Sunxperous 原来是一个愚蠢的错误导致了这个问题。请看下面的答案。 (我还没有等到明天将其标记为已回答)。

标签: ruby-on-rails


【解决方案1】:

我已经解决了这个问题,问题是在我在视图中实现的循环中添加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

【讨论】:

【解决方案2】:

如果您的 PlayerSession 表有一个名为 alias 的列,那么您的外键也应该是 alias,而不是 player_alias。作为一个建议,我会警惕使用别名作为外键:如果您的玩家可以/决定更改他的别名,那么您数据库中的所有 PlayerSession 记录都将变为无效并需要更新。使用不可变参数(例如player_id)比使用现有的别名列恕我直言。

【讨论】:

  • 别名是玩家的用户名。所以无法更改。这就像决定更改您的电子邮件地址并保留所有电子邮件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多