Rails 协会,我如何指定这种关系?
Rails associations, how can I specify this relationship?
OS: Windows 7
Rails: 4.2.0
你好,如果我有两个模型,可以说 Game 和 Team.
一个游戏可以有多个战队,但战队也可以属于多个游戏。
我似乎想不出正确的方法,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_to
和 has_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
OS: Windows 7 Rails: 4.2.0
你好,如果我有两个模型,可以说 Game 和 Team.
一个游戏可以有多个战队,但战队也可以属于多个游戏。
我似乎想不出正确的方法,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_to
和has_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