Ruby on rails Rails-添加双向关系
我正在尝试设置一个跟踪足球比赛的示例应用程序。目前有3个表: 场地-特定团队的主场 团队-实际的团队本身 游戏-一场可以容纳两支球队的游戏 我可以成功地查询这场比赛中有哪两支球队,但我很难将其逆转,并询问这支球队参加了哪场比赛 我已经用rails 5.1.7设置了一个新的rails项目,并一直在使用rails控制台查询数据 迁移 地 游戏 团队 模型 地 我希望能够获得一个团队的游戏列表:Ruby on rails Rails-添加双向关系,ruby-on-rails,activerecord,migration,Ruby On Rails,Activerecord,Migration,我正在尝试设置一个跟踪足球比赛的示例应用程序。目前有3个表: 场地-特定团队的主场 团队-实际的团队本身 游戏-一场可以容纳两支球队的游戏 我可以成功地查询这场比赛中有哪两支球队,但我很难将其逆转,并询问这支球队参加了哪场比赛 我已经用rails 5.1.7设置了一个新的rails项目,并一直在使用rails控制台查询数据 迁移 地 游戏 团队 模型 地 我希望能够获得一个团队的游戏列表: Team.first.games Team Load (0.0ms) SELECT "teams"
Team.first.games
Team Load (0.0ms) SELECT "teams".* FROM "teams" ORDER BY "teams"."id" ASC LIMIT ? [["LIMIT", 1]]
NoMethodError: undefined method `games' for #<Team:0x5a53fa0>
from (irb):1
我肯定错过了一些东西,但我希望这是可能的。如果有人能解释一下,我真的很感激!提前谢谢
但我正在努力扭转这种局面,并询问这支球队在哪场比赛中获胜
参加
如果您想找到一个团队在其中玩过的所有游戏,可以使用以下方法:
team = Team.find(1) # or any other criteria to find the team you want to get the games for
Game.where(team_one: team).or(Game.where(team_two: team))
你可以得到下面这样的游戏。这很重要。如果没有取消作用域,查询将无法正确运行
class Team < ApplicationRecord
has_one :ground
has_many :games, lambda { |team|
unscope(:where)
.where('team_one_id = ? OR team_two_id = ?', team.id, team.id)
}
end
t1 = Team.first
t1.games
#=> [Game id: 1, team_one_id: 1, team_two_id: 2, ..]
t2 = Team.second
t2.games
#=> [Game id: 1, team_one_id: 1, team_two_id: 2, ..]
首先,回答一个简单的例子:使用你的游戏模型,我们可以很容易地列出一支球队在主场玩的游戏,我希望这是正确的术语。我假设,从你的数据结构来看,第一队是比赛的东道主。因此,我们得到如下结果:
class Team
has_many :home_games, class_name: 'Game', foreign_key: :team_one
has_many :away_games, class_name: 'Game', foreign_key: :team_two
end
但要列出一支球队的所有比赛,我们可以做几件事:
效率最低但非常简单/幼稚的实施:
def games
home_games + away_games
end
这将获取所有主客场游戏,转换为数组并添加/连接数组,但无法在以后添加位置、排序等
更好的方法是使用数据库
def games
Game.where("team_one_id = ? or team_two_id = ?", self.id, self.id)
end
在rails 5中,您也可以将其编写为Game.whereteam\u one\u id:self.id.orGame.whereteam\u two\u id:self.id,但我仍然更喜欢旧的方式,因为它更可读,输入更少
然后你就可以写一些像
@team = Team.find(params[:id])
@games = @team.games.order(:game_time)
Team.first.games
Team Load (0.0ms) SELECT "teams".* FROM "teams" ORDER BY "teams"."id" ASC LIMIT ? [["LIMIT", 1]]
NoMethodError: undefined method `games' for #<Team:0x5a53fa0>
from (irb):1
team = Team.find(1) # or any other criteria to find the team you want to get the games for
Game.where(team_one: team).or(Game.where(team_two: team))
class Team < ApplicationRecord
has_one :ground
has_many :games, lambda { |team|
unscope(:where)
.where('team_one_id = ? OR team_two_id = ?', team.id, team.id)
}
end
t1 = Team.first
t1.games
#=> [Game id: 1, team_one_id: 1, team_two_id: 2, ..]
t2 = Team.second
t2.games
#=> [Game id: 1, team_one_id: 1, team_two_id: 2, ..]
class Game < ApplicationRecord
belongs_to :team_one, :class_name => "Team"
belongs_to :team_two, :class_name => "Team"
scope :by_team, -> (team) {
where(team_one_id: team.id).or(where(team_two_id: team.id))
}
end
Game.by_team(Team.first)
class Team
has_many :home_games, class_name: 'Game', foreign_key: :team_one
has_many :away_games, class_name: 'Game', foreign_key: :team_two
end
def games
home_games + away_games
end
def games
Game.where("team_one_id = ? or team_two_id = ?", self.id, self.id)
end
@team = Team.find(params[:id])
@games = @team.games.order(:game_time)