Mit arel
können Sie ziemlich weit. Der schwierige Teil ist, wie schreiben Sie nicht Ihre gesamte Abfrage mit arel
eigene Abfragesyntax?
Hier ist ein Trick: Wenn Sie Ihre Abfrage mit where
erstellen, wenn Sie arel
Bedingungen verwenden, erhalten Sie einige zusätzliche Methoden kostenlos. Zum Beispiel können Sie die Unterabfrage, die Sie dort haben, mit .exists.not
, die Sie erhalten eine (NOT (EXISTS (subquery)))
werfen, dass in Eltern where
-Klausel und Sie sind gesetzt.
Die Frage ist, wie verweisen Sie auf die beteiligten Tabellen? Sie brauchen Arel dafür. Sie könnte verwenden Arels where
mit seinen hässlichen Bedingungen wie a.eq b
. Aber warum? Da es sich um eine Gleichheitsbedingung handelt, können Sie stattdessen die Bedingungen von Rails verwenden!Sie können die Tabelle, die Sie abfragen, mit einem Hash-Schlüssel referenzieren, aber für die andere Tabelle (in der äußeren Abfrage) können Sie arel_table
verwenden. Watch this:
parents = Parent.arel_table
Parent.where(
Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)
Sie können sogar Arel Verbrauch verringern durch den Rückgriff ein wenig, und unter Berufung auf die Tatsache, Strings, die Sie where
in Unterabfragen als Parameter an Rails' füttern können. Es bringt wenig Nutzen, aber es zwingt Sie nicht zu sehr in Arels Methoden zu graben, also können Sie diesen Trick oder andere SQL-Operatoren verwenden, die eine Unterabfrage durchführen (gibt es noch andere?):
parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
Child.where(parent_id: parents[:id], other_parent_id: nil)
)
die beiden wichtigsten Punkte sind hier:
- Sie Subqueries gerade die gleiche Art und Weise bauen können Sie für den Aufbau regelmäßige Abfragen verwendet werden, verweisen die Tabelle des äußeren Abfrage mit Arel. Es kann nicht einmal ein echter Tisch sein, es kann ein Alias sein! Verrücktes Zeug.
- Sie können Unterabfragen als Parameter für Rails '
where
Methode gut verwenden.
'OtherParent' und' Parent' Modelle sind anders? –
Können Sie die Modellassoziationen anzeigen? –
Dies wird Exact Relational Division genannt. Siehe http://dba.stackexchange.com/questions/45829/what-is-the-name-of-this-type-of-query-and-what-is-anefficient-example –