Rails 协会,我如何指定这种关系?

Rails associations, how can I specify this relationship?

OS: Windows 7 Rails: 4.2.0

你好,如果我有两个模型,可以说 GameTeam.

一个游戏可以有多个战队,但战队也可以属于多个游戏。

我似乎想不出正确的方法,Belongs_to_many 不存在,我不认为团队可以 have_many 游戏和游戏可以 have_many 队。

has_and_belongs_to_many

我相信是你需要的

has_and_belongs_to_many

http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many

或者您创建一个加入模型(例如 TeamMembership),belongs_to 团队和游戏

您想使用 has_and_belongs_to_many 协会。

您的模型应如下所示:

class Games < ActiveRecord::Base
  has_and_belongs_to_many :teams #append this line to your model
end

class Teams < ActiveRecord::Base
  has_and_belongs_to_many :games #append this line to your model
end

您还需要像这样为游戏和团队创建连接 table:

class CreateGamesTeams < ActiveRecord::Migration
  def change
    create_table :gamess_teams do |t|
      t.integer :game_id
      t.integer :team_id
    end
  end
end

记得 运行 rake db:migrate 创建此连接 table。

有两种方法可以解决这个问题:

  • 一个就像@Alex Pan的回答:使用has_and_belongs_to_many
  • 另一个使用 belongs_tohas_many 关系与结点 table。
    • game.rb中:
      • has_many :game_team_maps
      • has_many :teams, through: :game_team_maps
    • team.rb
      • has_many :game_team_maps
      • has_many :games, through: :game_team_maps
    • game_team_map.rb
      • belongs_to :game
      • belongs_to :team

在我看来,第二种方式更灵活,也更容易维护。我选择它用于我自己的项目。

railscast 中有一个非常详细和有用的转换可以帮助您解决这个问题:http://railscasts.com/episodes/47-two-many-to-many

虽然 has_and_belongs_to_many 当然是一个有效的选项,但我所知道的大多数 "games" 都有主队和客队,所以做这样的事情可能是有意义的:

class Game < ActiveRecord::Base
  belongs_to :home_team, class_name: 'Team'
  belongs_to :away_team, class_name: 'Team'
end

class Team < ActiveRecord::Base
  has_many :home_games, class_name: 'Game', foreign_key: :home_team_id
  has_many :away_games, class_name: 'Game', foreign_key: :away_team_id
end

你也可以用 has_many :through:

来建模
class Game < ActiveRecord::Base
  has_many :team_games
  has_many :games, through: :team_games
end

class TeamGame < ActiveRecord::Base
  belongs_to :game
  belongs_to :team

  scope :home, -> { where(home: true) }
  scope :away, -> { where(home: false) }
end

class Team < ActiveRecord::Base
  has_many :team_games
  has_many :games, through: :team_games
  has_many :home_games, -> { TeamGame.home }, through: :team_games, source: :game, class_name: 'TeamGame'
  has_many :away_games, -> { TeamGame.away }, through: :team_games, source: :game, class_name: 'TeamGame'
end