场景:
Team
has_many :players, dependent: :destroy
has_many :users, through: :players
Player
belongs_to :team
belongs_to :user
User
所以,假设我有 4 个拥有不同用户的团队:
Team 1
User 1, User 2
Team 2
User 2, User 3
Team 3
User 1
Team 4
User 2, User 4, User 5
现在,假设我有两个用户的 ID(用户 1
、用户 5
),并且我想知道是否有任何团队由 <仅限这两名球员。假设我有一个由用户 1、2 和 5 组成的团队。查询不应包含该团队。
我如何使用有利于我的ActiveRecord
语义来做到这一点?从一个团队中获取所有玩家很容易,但我找不到相反的方法。
最佳答案
更新:啊!我用纯 SQL 得到了它:
users = User.first(2)
Team.joins(:users).group('teams.id').having('SUM( CASE WHEN users.id in (?) THEN 1 ELSE -1 END ) = ?', users, users.count)
尝试一下并告诉我它是否适合您(在这里工作: http://sqlfiddle.com/#!17/bb2a9/8 和相同的示例,但有 3 个玩家: http://sqlfiddle.com/#!17/bb2a9/10 )
这没有在数据库级别进行优化,因为它使用了大量的 ruby/rails 代码,但是你可以尝试一下吗?
users = User.first(2)
# find teams with that exact number of players associated
teams = Team.joins(:users).group('teams.id').having('COUNT(users.id) = ?', users.count)
# find players referencing to those teams with other users than the ones specified
players_to_ignore = Player.where(team_id: teams).where('user_id NOT IN (?)', users)
# get Teams where associated players id is not in the previous list
Team.where(id: teams).joins(:players).where('players.id NOT IN (?)', players_to_ignore)
关于sql - 对 has_many 进行反向查询 :through,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45703606/