簡體   English   中英

Rails 5 通過關聯模型更新 has_many

[英]Rails 5 update has_many through associates models

我有以下型號

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中添加具有角色的新玩家、更新具有新角色的玩家以及從我的團隊中移除該玩家應該是什么樣的?

這只是一個可能的解決方案的開始,它與您添加的一些模型和數據庫驗證非常相似。 其中一些驗證確保每個三向關系 ( FilledTeamRole ) 的唯一性,因此需要處理嘗試創建重復記錄的錯誤,或者您可以過濾可以選擇的每個類的可能 id,以便無法創建重復項。

一個完整的解決方案將取決於您想要TeamPlayerRole類之間的其他關聯,而不是需要所有三個類的關聯。 例如,您是否想要/需要TeamPlayer之間的關聯,其中僅在這兩個類之間存在關系而無需RoleTeamPlayer id: 1, team_id: 1, player_id: 1 )。 如果需要這些關系,則需要額外的代碼來實現這一點,我已經擁有並可以提供建議。

至於你的控制器是什么樣子,你可以使用filled_team_roles控制器(或者可能創建一個儀表板控制器),提供實例變量@teams@players@roles來為表單中的每個類填充下拉菜單以創建filled_team_roles關系。 您還可以在每個其他類中使用其他表單,其中使用兩個下拉列表而不是三個下拉列表,其中第三個值是表單所在控制器的類的所選模型 ID(例如, players_controlleredit操作,帶有下拉菜單) teamrole下降)

~/app/models/team.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

~/app/models/player.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

~/app/models/role.rb

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

~/app/models/filled_team_role.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

~/db/migrate/20170127041000_create_team.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

~/db/migrate/20170127041100_create_player.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

~/db/migrate/20170127041200_create_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

~/db/migrate/20170127051300_create_filled_team_role.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

~/db/seeds.rb

Team.create(name: 'Los Angeles Dodgers', sport: 'baseball', city: 'Los Angeles', state: 'CA', country: 'United States')
Team.create(name: 'New York Yankees',    sport: 'baseball', city: 'New York',    state: 'NY', country: 'United States')
Team.create(name: 'Chicago Cubs',        sport: 'baseball', city: 'Chicago',     state: 'IL', country: 'United States')
Team.create(name: 'St. Louis Cardinals', sport: 'baseball', city: 'St. Louis',   state: 'MO', country: 'United States')
Player.create(first_name: 'Max',   last_name: 'Walker', full_name_surname_first: 'Walker, Max', ssn: '123-45-6789')
Player.create(first_name: 'Homer', last_name: 'Winn',   full_name_surname_first: 'Winn, Homer', ssn: '234-56-7890')
Player.create(first_name: 'Will',  last_name: 'Steel',  full_name_surname_first: 'Steel, Will', ssn: '345-67-8901')
Player.create(first_name: 'Lucky', last_name: 'Snag',   full_name_surname_first: 'Snag, Lucky', ssn: '456-78-9012')
Role.create(name: 'pitcher')
Role.create(name: 'catcher')
Role.create(name: 'first baseman')
Role.create(name: 'second baseman')
Role.create(name: 'shortstop')
Role.create(name: 'third baseman')
Role.create(name: 'right fielder')
Role.create(name: 'center fielder')
Role.create(name: 'left fielder')
FilledTeamRole.create(team_id: 1, player_id: 1, role_id: 1)
FilledTeamRole.create(team_id: 2, player_id: 2, role_id: 2)
FilledTeamRole.create(team_id: 3, player_id: 3, role_id: 3)
FilledTeamRole.create(team_id: 4, player_id: 4, role_id: 4)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM