2016-07-28 6 views
1

Ich habe drei Tabellen:Wie einfach n-zu-n-Verbindung in Schienen zu verbinden?

user has_many locations_users 
user has_many locations :through => locations_users 

location has_many locations_users 
location has_many users :through => locations_users 

Wie würde ich alle Nutzer finden, die miteinander verbunden sind = 5 in einer Abfrage LOCATION_ID: users, locations, locations_users, Die Verbände sind wie folgt?

Jede Hilfe wäre willkommen.

Antwort

1

Ich weiß nicht 1 Abfrage Weg, aber die folgende Lösung ist effizient.

a = User.where("id NOT IN (?)", LocationUser.pluck("DISTINCT user_id")) 
b = LocationUser.where(location_id: 5).pluck("DISTINCT user_id") 
result = User.where(id: a+b) 
2

Sie können LEFT OUTER JOIN verwenden. Es holt alle Daten aus der linken Tabelle mit Daten von rechts passend, falls vorhanden (falls nicht vorhanden, Join-Spalte ist null):

User 
    .joins('LEFT OUTER JOIN locations_users ON locations_users.user_id = users.id') 
    .where('locations_users.id IS NULL OR locations_users.location_id = ?', 5) 
    .all 

Hovewer:

  • diese Abfrage verwendet join, die Leistung ist kann arm an großen Tischen (vielleicht zwei Abfragen werden schneller durchführen - testen Sie es!)
  • für eine bessere Leistung, stellen Sie sicher, dass Indizes für verknüpften Spalten
+0

gesetzt sind wahrscheinlich Sie meinen 'OR' anstelle von "AND" in den Kriterien. –

+0

Ja. Korrigiert. – maicher

+0

Diese Antwort passt am besten zu der Frage, aber die linke Verbindung ist langsam wie die Hölle ... – emrahbasman