【发布时间】:2017-01-18 10:55:42
【问题描述】:
我在 Rails 应用中有两个模型 - Tournament 和 Player 通过连接表关联:
class Tournament < ApplicationRecord
has_many :tournament_players
has_many :players, through: :tournament_players
end
class Player < ApplicationRecord
has_many :tournament_players
has_many :tournaments, through: :tournament_players
scope :selected, -> (tournament) { includes(:tournaments).where(tournaments: {id: tournament.id}) }
end
我有很多锦标赛,每个锦标赛都可以有很多玩家。玩家可以参加许多锦标赛。范围
scope :selected, -> (tournament) { includes(:tournaments).where(tournaments: {id: tournament.id}) }
以锦标赛为参数,成功找到所有已添加到锦标赛的玩家。
我想要的是一个相反的范围 - 返回所有尚未添加到给定锦标赛中的玩家。我试过了
scope :not_selected, -> (tournament) { includes(:tournaments).where.not(tournaments: {id: tournament.id}) }
但这会返回许多相同的玩家,我认为是因为这些玩家作为其他锦标赛的一部分存在。对应的 SQL 类似于:
SELECT "players".*, "tournaments”.* FROM "players" LEFT OUTER JOIN
"tournament_players" ON "tournament_players"."player_id" =
"players"."id" LEFT OUTER JOIN "tournaments" ON "tournaments"."id" =
"tournament_players"."tournament_id" WHERE ("tournaments"."id" != $1)
ORDER BY "players"."name" ASC [["id", 22]]
我也尝试了this question 上的建议 - 使用
scope :not_selected, -> (tournament) { includes(:tournaments).where(tournaments: {id: nil}) }
但这似乎不起作用 - 它只是返回一个空数组,我再次认为是因为玩家作为单独锦标赛的一部分存在于连接表中。对应的 SQL 类似于:
SELECT "players”.*, "tournaments”.* FROM "players" LEFT OUTER JOIN
"tournament_players" ON "tournament_players"."player_id" =
"players"."id" LEFT OUTER JOIN "tournaments" ON "tournaments"."id" =
"tournament_players"."tournament_id" WHERE "tournaments"."id" IS NULL
ORDER BY "players"."name" ASC
【问题讨论】:
-
查看我的编辑 - 据我所知,这些解决方案并不完全正确。
-
你能显示生成的SQL吗?
-
添加了 sql。我只是无法理解我需要的搜索!
标签: sql ruby-on-rails ruby rails-activerecord jointable