Dans ARel, le where()
Les méthodes peuvent prendre des tableaux comme arguments pour générer une requête "WHERE id IN...". Ce que vous avez écrit va donc dans le bon sens.
Par exemple, le code ARel suivant :
User.where(:id => Order.where(:user_id => 5)).to_sql
... ce qui équivaut à :
User.where(:id => [5, 1, 2, 3]).to_sql
... produirait le SQL suivant sur une base de données PostgreSQL :
SELECT "users".* FROM "users" WHERE "users"."id" IN (5, 1, 2, 3)"
Mise à jour : en réponse aux commentaires
Ok, j'ai mal compris la question. Je crois que vous voulez que la sous-requête énumère explicitement les noms des colonnes qui doivent être sélectionnées afin d'éviter de soumettre la base de données à deux requêtes (ce que fait ActiveRecord dans le cas le plus simple).
Vous pouvez utiliser project
pour le select
dans votre sous-sélection :
accounts = Account.arel_table
User.where(:id => accounts.project(:user_id).where(accounts[:user_id].not_eq(6)))
... ce qui produirait le SQL suivant :
SELECT "users".* FROM "users" WHERE "users"."id" IN (SELECT user_id FROM "accounts" WHERE "accounts"."user_id" != 6)
J'espère sincèrement que je vous ai donné ce que vous vouliez cette fois-ci !