1

我正在尝试创建两个本质上相同但具有两个不同名称的关联,因为它们的含义不同。我有一种感觉,这是一个我不能完全正确的语法问题。我宁愿不重写基本级别的模型,但我愿意接受建议。就建模而言:突袭有玩家。突袭有领导者(即玩家)。我希望这个玩家袭击协会存在于 player_raids 表和领导者_raids 表中。两组方法调用需要互补:players.raids 和 raids.players,以及 player.raids_led 和 raids.leaders。

播放器.rb:

class Player < ActiveRecord::Base
  has_many :players_raids, class_name: 'PlayersRaids'
  has_many :raids, through: :players_raids
  has_many :leaders_raids, class_name: 'LeadersRaids'
  has_many :raids_led, through: :leaders_raids, source: :leader, foreign_key: 'leader_id'
end

突袭.rb:

class Raid < ActiveRecord::Base
  has_many :players_raids, class_name: 'PlayersRaids'
  has_many :players, through: :players_raids
  has_many :leaders_raids, class_name: 'LeadersRaids'
  has_many :leaders, through: :leaders_raids
end

player_raids.rb:

class PlayersRaids < ActiveRecord::Base
  belongs_to :player
  belongs_to :raid
end

leader_raids.rb:

class LeadersRaids < ActiveRecord::Base
  belongs_to :leader, class_name: 'Player'
  belongs_to :raid
end

create_players_raids.rb

class CreatePlayersRaids < ActiveRecord::Migration
  def change
    create_table :players_raids, id: false do |t|
      t.references :player
      t.references :raid
      t.timestamps
    end
  end
end

创建_leaders_raids.rb

class CreateLeadersRaids < ActiveRecord::Migration
  def change
    create_table :leaders_raids, id: false do |t|
      t.integer :leader_id
      t.references :raid
      t.timestamps
    end
  end
end

raids_controller.rb

class RaidsController < ApplicationController
  def create
    @raid = Raid.new(params[:raid])
    @raid.leaders << current_player
    @raid.players << current_player
    if @raid.save
      redirect_to raid_path(@raid), notice: "#{@raid.name} created!"
    else
      render 'new'
    end
  end
end

其中一些部分是我一直在玩的领域,即 Player 模型中的 'raids_led' 关联上的 'source' 和 'foreign_key' 字段以及当前为 't.integer :leader_id' 的名称/引用LeadersRaids 表迁移文件。

创建新团队时,应将 current_player(我的 ApplicationController 版本的 current_user 作为我的 Player 模型是更常见的 User 模型)添加为新创建的团队的玩家和领导者。当我使用 raid.players、raid.leaders 和 player.raids 时,我得到的结果完全符合我的预期。但是,当我使用 player.raids_led 时,我收到一个错误,它试图使用 raids_leaders.player_id 而不是 raids_leaders.leader_id (ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'leaders_raids.player_id' in 'where clause': SELECT players.* 从内部连接开始. = . playersWHERE . = 1)。谁能帮我解决我的语法缺失的地方?leaders_raidsplayersidleaders_raidsleader_idleaders_raidsplayer_id

编辑: 我更新了这些模型,它似乎按照我的初衷运作。也许这只是一些睡眠和一个新的视角。如果有更好的方法,请随时更新或评论。

播放器.rb:

class Player < ActiveRecord::Base
  has_many :characters
  has_many :players_raids, class_name: 'PlayersRaids'
  has_many :raids, through: :players_raids
  has_many :leaders_raids, class_name: 'LeadersRaids'
  has_many :raids_led, through: :leaders_raids, source: :raid
end

突袭.rb:

class Raid < ActiveRecord::Base
  has_many :players_raids, class_name: 'PlayersRaids'
  has_many :players, through: :players_raids
  has_many :leaders_raids, class_name: 'LeadersRaids'
  has_many :leaders, through: :leaders_raids, source: :leader
end

leader_raids.rb:

class LeadersRaids < ActiveRecord::Base
  belongs_to :leader, class_name: 'Player', foreign_key: 'player_id'
  belongs_to :raid
end

create_leaders_raids.rb:

class CreateLeadersRaids < ActiveRecord::Migration
  def change
    create_table :leaders_raids, id: false do |t|
      t.integer :player_id
      t.references :raid
      t.timestamps
    end
  end
end
4

0 回答 0