Ruby on 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"

我正在尝试设置一个跟踪足球比赛的示例应用程序。目前有3个表:

场地-特定团队的主场 团队-实际的团队本身 游戏-一场可以容纳两支球队的游戏 我可以成功地查询这场比赛中有哪两支球队,但我很难将其逆转,并询问这支球队参加了哪场比赛

我已经用rails 5.1.7设置了一个新的rails项目,并一直在使用rails控制台查询数据

迁移 地 游戏 团队 模型 地 我希望能够获得一个团队的游戏列表:

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)