2017-02-12 3 views
0

Ich versuche, eine Liste aller Datensätze, die nicht in einer Join-Tabelle vorhanden sind.Active Record wo Join Tabelle Datensatz existiert nicht

Die Modelle sind User, Game und MarkedGame, wo Benutzer Spiele als gespielt markieren können. Es ist ein viel zu viele Beziehung:

User > MarkedGame < Game 

Was ich will, eine Liste aller Spiele ist, dass nicht vom Benutzer markiert.

Ich weiß, dass ich zwei separate Abfragen tun könnte und subtrahieren sie:

Game.all - current_user.games 

Aber Ich mag nicht, dass dies lässt mich mit einem Array statt eines Active Record Beziehungsobjekt. Plus es scheint, als sollte es eine leistungsfähigere Art, es zu tun.

Wenn es keine Active Record Möglichkeit gibt, dies zu handhaben, gibt es vielleicht einen SQL-Weg? Mein roher SQL ist nicht besonders stark, also würde jede mögliche Hilfe geschätzt.

Danke.

Antwort

1

Das sollte es tun. Gibt alle Spiele zurück, die nicht vom aktuellen Benutzer markiert wurden.

Game.where('id not in (select game_id from marked_games where user_id = ?)', current_user.id) 
+1

Perfect! Vielen Dank. Also ist das im Grunde gesagt, wo die Game-ID ist nicht in einer Unterabfrage von Game-IDs? –

+0

Ja, und es ist nur eine Abfrage, also ist es ziemlich schnell, wenn Sie die richtigen Indizes in Ihrer Datenbank haben. – Iceman

+0

Großartig, nochmals vielen Dank. Die andere Antwort von Potashin funktioniert auch perfekt, hast du eine Meinung, welche ist die bessere Lösung? –

2

können Sie versuchen, die folgenden:

Game.where.not(id: MarkedGame.where(user_id: current_user.id).pluck(:game_id)) 
+0

Auch funktioniert perfekt, danke! Hast du eine Meinung, ob deine besser oder schlechter ist als die obige? Versuchen herauszufinden, welche als die Antwort zu markieren –