Rails 5通过关联模型更新has_many

时间:2017-01-27 23:10:38

标签: ruby-on-rails polymorphic-associations

我有以下模特

class TeamPlayer < ApplicationRecord
  belongs_to :team
  belongs_to :player
  belongs_to :role
end

class Team < ApplicationRecord
  has_many :team_players
  has_many :players, :through => :team_players
end

class Role < ApplicationRecord
  has_many :team_players
  has_many :players, :through => :team_players
end

class Player < ApplicationRecord
  has_many :team_players
  has_many :teams, :through => :team_players

  has_many :roles, :through => :team_players
end

基本上,我想为团队中的不同玩家分配不同的角色。

id  team_id     player_id   role_id 
2   1           2           1   
3   3           2           1   
4   1           1           2   

teams_controller.rb中添加具有角色的新玩家,更新具有新角色的玩家以及从我的团队中删除该玩家应该是什么样的?

1 个答案:

答案 0 :(得分:1)

这只是可能解决方案的开始,它与您添加的某些模型和数据库验证的内容非常相似。其中一些验证确保了每个三向关系(FilledTeamRole)的唯一性,因此需要处理尝试创建重复记录的错误,或者您可以过滤每个类的可能ID。选中此选项,以便无法创建副本。

完整的解决方案将取决于您需要TeamPlayerRole类之间的其他关联,而不是需要全部三种类别的关联。例如,您是否希望/需要TeamPlayer之间的关联,其中只有这两个类之间存在关系,而不需要RoleTeamPlayer {{1 }})。如果需要这些关系,那么将需要额外的代码来实现这一点,我已经并且可以作为建议提供。

就控制器的外观而言,您可以使用id: 1, team_id: 1, player_id: 1控制器(或者可能创建仪表板控制器),提供实例变量filled_team_roles@teams和{{1填充表单中每个类的下拉菜单以创建@players关系。您还可以在其他每个类中使用其他表单,其中使用两个下拉列表而不是三个下拉列表,其中第三个值是表单所在的控制器类的所选模型ID(例如,@roles中的filled_team_roles操作edit包含players_controllerteam

的下拉列表

<强>〜/应用/模型/ team.rb

role

<强>〜/应用/模型/ player.rb

class Team < ApplicationRecord
  has_many :filled_team_roles, dependent: :destroy
  validates :name, uniqueness: { scope: [:sport, :city] }
  scope :by_name_asc, -> { order(name: :asc) }
end

<强>〜/应用/模型/ role.rb

class Player < ApplicationRecord
  has_many :filled_team_roles, dependent: :destroy
  validates_uniqueness_of :ssn
  scope :by_name_asc, -> { order(last_name: :asc, first_name: :asc) }
end

<强>〜/应用/模型/ filled_team_role.rb

class Role < ApplicationRecord
  has_many :filled_team_roles, dependent: :destroy
  validates_uniqueness_of :name
  scope :by_name_asc, -> { order(name: :asc) }
end

<强>〜/分贝/迁移/ 20170127041000_create_team.rb

class FilledTeamRole < ApplicationRecord
  belongs_to :team
  belongs_to :player
  belongs_to :role
  validates :team_id,   presence: true
  validates :player_id, presence: true
  validates :role_id,   presence: true
  validates :team_id, uniqueness: { scope: [:player_id, :role_id] }    
end

<强>〜/分贝/迁移/ 20170127041100_create_player.rb

class CreateTeam < ActiveRecord::Migration[5.0]
  def change
    create_table :teams do |t|
      t.string :name
      t.string :sport
      t.string :city
      t.string :state
      t.string :country
      t.timestamps null: false
    end
    add_index :teams, [:name, :sport, :city], unique: true
  end
end

<强>〜/分贝/迁移/ 20170127041200_create_role.rb

class CreatePlayer < ActiveRecord::Migration[5.0]
  def change
    create_table :players do |t|
      t.string :first_name
      t.string :last_name, index: true
      t.string :full_name_surname_first
      t.string :ssn, index: { unique: true }
      t.timestamps null: false
    end
  end
end

<强>〜/分贝/迁移/ 20170127051300_create_filled_team_role.rb

class CreateRole < ActiveRecord::Migration[5.0]
  def change
    create_table :roles do |t|
      t.string :name, index: { unique: true }
      t.timestamps null: false
    end
  end
end

<强>〜/分贝/ seeds.rb

class CreateFilledTeamRole < ActiveRecord::Migration[5.0]
  def change
    create_table :filled_team_roles do |t|
      t.timestamps null: false
      t.references :team
      t.references :role
      t.references :player
    end
    add_index :filled_team_roles,
             [:team_id, :player_id, :role_id],
               unique: true,
               name: 'index_filled_team_roles_unique_combination_of_foreign_keys'
  end
end