在Rails中设计关系的建议

时间:2014-09-03 01:00:16

标签: ruby-on-rails activerecord

我需要连接2个玩家连接表。该连接表必须具有活动标志,并且可能还有更多属性。我希望能够将2 PlayersPlayerLinkactive_player以及passive_player相关联,以便我可以说player_link.active_player.name

我尝试了以下但是没有得到我想要的行为。也许我错过了一些愚蠢的东西,或者错误地接近它。

module V1
  class Player < ActiveRecord::Base

    belongs_to :player_link

  end    
end

module V1
  class PlayerLink < ActiveRecord::Base

    has_one :active_player, class_name: "Player", foreign_key: :active_player_id
    has_one :passive_player, class_name: "Player", foreign_key: :passive_player_id
  end
end

schema.rb条目:

create_table "player_links", force: true do |t|
    t.integer  "active_player_id"
    t.integer  "passive_player_id"
    t.boolean  "active"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

爆炸的测试查询:

V1::PlayerLink.where(active: true).each do |l|
  l.active_player.update_attribute(:foo, bar)
  l.passive_player.update_attribute(:foo, bar
end

错误:

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: players.active_player_id: SELECT  "players".* FROM "players"  WHERE "players"."active_player_id" = ?

奖励:为什么Rails再次查询players

1 个答案:

答案 0 :(得分:1)

这些被称为自引用关联 - 我第一次做这些时也遇到了麻烦。

尝试按如下方式修改控制器逻辑:

module V1
  class Player < ActiveRecord::Base

    has_many :player_links

  end    
end

module V1
  class PlayerLink < ActiveRecord::Base

    belongs_to :player, :foreign_key => "active_player_id"
    belongs_to :passive_player, :class_name => "Player", :foreign_key => "passive_player_id"

  end
end

有关详细信息,请参阅RailsCast #163