В ARel методы where()
могут принимать массивы в качестве аргументов, которые будут генерировать запрос «ГДЕ id IN...». Так что то, что вы написали, в правильном направлении.
Например, следующий код ARel:
User.where(:id => Order.where(:user_id => 5)).to_sql
... что эквивалентно:
User.where(:id => [5, 1, 2, 3]).to_sql
... выведет следующий SQL в базу данных PostgreSQL:
SELECT "users".* FROM "users" WHERE "users"."id" IN (5, 1, 2, 3)"
Обновление: в ответ на комментарии
Итак, я неправильно понял вопрос. Я считаю, что вы хотите, чтобы подзапрос явно перечислял имена столбцов, которые должны быть выбраны, чтобы не попасть в базу данных двумя запросами (что и делает ActiveRecord в простейшем случае).
Вы можете использовать project
вместо select
в своем дополнительном выборе:
accounts = Account.arel_table
User.where(:id => accounts.project(:user_id).where(accounts[:user_id].not_eq(6)))
... который выдаст следующий SQL:
SELECT "users".* FROM "users" WHERE "users"."id" IN (SELECT user_id FROM "accounts" WHERE "accounts"."user_id" != 6)
Я искренне надеюсь, что на этот раз я дал вам то, что вы хотели!
person
Scott
schedule
18.04.2011