2016-05-06 13 views
2

ich eine Gaming-Plattform entwickle und ich habe die folgenden (vereinfacht) Modelle:Fügen Sie alle IDs in Active Abfrage

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 

Ich brauche eine Activerecord-Abfrage durchzuführen, die von einer bestimmten Gruppe für alle Spiele gespielt sieht der Benutzer. Um zum Beispiel der Daten gegeben:

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

Ich brauche einen Weg zu finden, um zu bestimmen, welche Spiele werden von den Spielern mit ids gespielt 39 und 41, die in diesem Fall die Spiele mit ids 10 und 13 sein würden. die Abfrage, die ich bisher gefunden habe, ist oben:

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

jedoch diese Abfrage zurückgibt, die Spiele, die von jeder dieser Spieler gespielt, statt der von beiden gespielten Spiele.

Antwort

1

Sie können es versuchen, wenn Sie zwei Abfrage ausführen und die Ergebnisse überschneiden:

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

Dies funktioniert, aber ich möchte 1 einzelne SQL - Abfrage durchgeführt werden, da die Anzahl der Spieler beliebig groß sein könnte – Bustikiller

+0

'Game.joins (: players) .where (Spieler: {id: 39}) : {id: 41}) '- versuche so etwas – dp7

1

Diese Funktion mehr wie eine SQL INTERSECT und sollten Sie die Ergebnisse, die Sie in diesem Fall benötigen:

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

Wirklich, die Magie passiert durch die Spiele der Auswahl, wo entweder Player abgespielt wird, und dann die Gruppierung von game.id die Ergebnisse zu denjenigen zu reduzieren, die mehr als ein game.id in der Ergebnisgruppe. Es ergeben sich folgende Ergebnisse aus der Rails-Konsole:

=> #<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">]> 

Beachten Sie, dass nur Spiele 10 und 13 (basierend auf den Beispieldaten) werden von dieser Lösung zurückgeführt. Die manuelle Überprüfung zeigt, dass nur die Spiele 10 und 13 beide Spieler 39 und 41 spielten.

Verwandte Themen