Include all ids in ActiveRecord query

落花浮王杯 提交于 2019-12-07 22:29:31

问题


I am developing a gaming platform and I have the following (simplified) models:

class Game < ActiveRecord:Base
  has_many :game_players
  has_many :players, through: :game_players
end

class Player < ActiveRecord:Base
  has_many :game_players
  has_many :games, through: :game_players
end

class GamePlayer < ActiveRecord:Base
  belongs_to :game
  belongs_to :player
end

I need to perform an ActiveRecord query that looks for all games played by a certain group of users. For example, given the data:

+---------+-----------+
| game_id | player_id |
+---------+-----------+
|      10 |        39 |
|      10 |        41 |
|      10 |        42 |
|      12 |        41 |
|      13 |        39 |
|      13 |        41 |
+---------+-----------+

I need to find a way to determine which games are played by the players with ids 39 and 41 which, in this case, would be the games with ids 10 and 13. The query I have found up to now is:

Game.joins(:players).where(players: {id: [39, 41]}).uniq

However, this query is returning the games played by any of these players, instead of the games played by both of them.


回答1:


You can give it a try if you can execute two query and intersect the results:

Game.joins(:players).where(players: {id: 39}) & Game.joins(:players).where(players: {id: 41}) 



回答2:


This functions more like a SQL INTERSECT, and should give you the results that you need in this case:

Game.joins(:players).where(players: {id: [39,41]}).group('"games"."id"').having('COUNT("games"."id") > 1')

Really, the magic happens by selecting the games where either player is playing, and then grouping by game.id to reduce the results to those having more than one game.id in the result group. It produces the following results from the Rails console:

 => #<ActiveRecord::Relation [#<Game id: 10, created_at: "2016-05-07 01:17:25", updated_at: "2016-05-07 01:17:25">, #<Game id: 13, created_at: "2016-05-07 01:17:25", updated_at: "2016-05-07 01:17:25">]>

Note that only games 10 and 13 (based on the sample data) are returned by this solution. Manual verification shows that only games 10 and 13 had both players 39 and 41 playing.



来源:https://stackoverflow.com/questions/37071651/include-all-ids-in-activerecord-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!