我正在尝试建立一个跟踪足球比赛的示例应用程序。当前有3张桌子:
我可以成功查询“哪个球队参加了这场比赛?”,但我正在努力扭转这种状况,并问“这个球队参加了哪些比赛?”
我已经用Rails 5.1.7设置了一个新的Rails项目,并一直在使用Rails控制台查询数据。
def change
create_table :grounds do |t|
t.string :ground_name
t.string :ground_location
t.belongs_to :team
t.timestamps
end
end
end
def change
create_table :games do |t|
t.timestamps
t.datetime :game_time
t.belongs_to :team_one
t.belongs_to :team_two
end
end
end
def change
create_table :teams do |t|
t.string :team_name
t.timestamps
end
end
end
class Ground < ApplicationRecord
belongs_to :team
end
class Game < ApplicationRecord
belongs_to :team_one, :class_name => "Team"
belongs_to :team_two, :class_name => "Team"
has_many :teams
end
class Team < ApplicationRecord
has_one :ground
end
我可以成功查询:
g1 = Game.new
g1.team_one = Team.first
g1.team_two = Team.second
g1.save
Game.first.team_one -> Correctly spits out team
Game.first.team_two -> Correctly spits out team
我希望能够获得一支球队的比赛清单:
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
我肯定会缺少一些东西,但希望这是可能的。如果有人能对此有所启示,我将非常感谢!预先感谢。
答案 0 :(得分:1)
您可以获取以下游戏。 unscope很重要。如果没有取消范围,查询将无法正确运行。
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, ..]
答案 1 :(得分:0)
但是我正在努力扭转这种局面,并问“哪个比赛有这支球队 玩过吗?”
如果您想查找一个团队参加过的所有比赛,可以使用#or
方法,如下所示:
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))
答案 2 :(得分:0)
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)
答案 3 :(得分:0)
首先,回答一个简单的案例:使用您的Game
模型,我们可以轻松列出球队在主场比赛和客场比赛中的比赛(我希望这是正确的术语)。我认为,根据您的数据结构,第1队将主持比赛。这样我们就得到了:
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
这将获取所有本垒打游戏,转换为数组并添加/连接数组,但是以后无法添加where
,排序等等...
更好的方法是使用数据库
def games
Game.where("team_one_id = ? or team_two_id = ?", self.id, self.id)
end
(在rails 5中,您也可以将其写为Game.where(team_one_id: self.id).or(Game.where(team_two_id: self.id))
,但我仍然更喜欢旧方法,因为它更具可读性和更少的键入性)
然后,您将可以编写类似
的内容@team = Team.find(params[:id])
@games = @team.games.order(:game_time)