Mit SQL kann ich einfach solche Unterabfragen durchführen
User.where(:id => Account.where(..).select(:user_id))
Dies erzeugt:
SELECT * FROM users WHERE id IN (SELECT user_id FROM accounts WHERE ..)
Wie kann ich dies mit Rails '3 activerecord / arel / meta_where tun?
Ich brauche / will echte Unterabfragen, keine Ruby-Problemumgehungen (mit mehreren Abfragen).
ruby-on-rails-3.1
subquery
arel
Gucki
quelle
quelle
not
Bedingung . Ich konnte dies in Rails 3 erreichen, indem ich den Ansatz in diesem Beitrag anpasste :subquery = Profile.select("user_id").where(gender: 'm')).to_sql; Message.where('user_id NOT IN (#{subquery}))
Grundsätzlich werdenActiveRecord
Methoden verwendet, um die abgeschlossene, ordnungsgemäß zitierte Unterabfrage zu erstellen, die dann in die äußere Abfrage eingefügt wird. Der Hauptnachteil ist, dass Unterabfrageparameter nicht gebunden sind.Message.where.not(user_id: Profile.select("user_id").where(gender: 'm'))
- das erzeugt eine Unterauswahl "NOT IN". Gerade mein Problem gelöst ..In ARel können die
where()
Methoden Arrays als Argumente verwenden, die eine Abfrage "WHERE id IN ..." generieren. Was Sie geschrieben haben, ist also in die richtige Richtung.Zum Beispiel der folgende ARel-Code:
... was entspricht:
... würde das folgende SQL in einer PostgreSQL-Datenbank ausgeben:
Update: als Antwort auf Kommentare
Okay, also habe ich die Frage falsch verstanden. Ich glaube, Sie möchten, dass die Unterabfrage die Spaltennamen, die ausgewählt werden sollen, explizit auflistet, um die Datenbank nicht mit zwei Abfragen zu treffen (was ActiveRecord im einfachsten Fall tut).
Sie können
project
für dieselect
in Ihrer Unterauswahl verwenden:... was das folgende SQL erzeugen würde:
Ich hoffe aufrichtig, dass ich Ihnen diesmal gegeben habe, was Sie wollten!
quelle
Ich habe selbst nach der Antwort auf diese Frage gesucht und mir einen alternativen Ansatz ausgedacht. Ich dachte nur, ich würde es teilen - hoffe, es hilft jemandem! :) :)
Bingo! Bango!
Funktioniert mit Schienen 3.1
quelle
subquery = Account.where(...).select(:id).to_sql
query = User.where("users.account_id IN (#{subquery})")
Eine andere Alternative:
quelle
Dies ist ein Beispiel für eine verschachtelte Unterabfrage mit Rails ActiveRecord und JOINs, in der Sie Klauseln zu jeder Abfrage sowie das Ergebnis hinzufügen können:
Sie können die verschachtelten Bereiche inner_query und Outer_query zu Ihrer Modelldatei hinzufügen und ...
Ein Beispiel für den Umfang:
quelle