activerecord中的子查询

随着续集,我可以很容易地做这样的子查询

User.where(:id => Account.where(..).select(:user_id)) 

这产生:

 SELECT * FROM users WHERE id IN (SELECT user_id FROM accounts WHERE ..) 

我怎样才能做到这一点使用rails'3 activerecord / arel / meta_where?

我确实需要/想要真正的子查询,没有ruby解决方法(使用几个查询)。

Rails现在默认这样做:)

 Message.where(user_id: Profile.select("user_id").where(gender: 'm')) 

会产生下面的SQL

 SELECT "messages".* FROM "messages" WHERE "messages"."user_id" IN (SELECT user_id FROM "profiles" WHERE "profiles"."gender" = 'm') 

在ARel中, where()方法可以将数组作为参数生成“WHERE ID IN …”查询。 所以你写的是正确的。

例如,以下ARel代码:

 User.where(:id => Order.where(:user_id => 5)).to_sql 

…相当于:

 User.where(:id => [5, 1, 2, 3]).to_sql 

…将在PostgreSQL数据库上输出以下SQL:

 SELECT "users".* FROM "users" WHERE "users"."id" IN (5, 1, 2, 3)" 

更新:回应评论

好的,所以我误解了这个问题。 我相信你希望子查询显式地列出要select的列名,以便不用两个查询(这是ActiveRecord在最简单的情况下所做的)来访问数据库。

您可以在您的子select中使用select project

 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) 

我真心希望这次给你你想要的东西!

我自己正在寻找这个问题的答案,并且提出了另一种方法。 我只是以为我会分享它 – 希望它可以帮助别人! 🙂

 # 1. Build you subquery with AREL. subquery = Account.where(...).select(:id) # 2. Use the AREL object in your query by converting it into a SQL string query = User.where("users.account_id IN (#{subquery.to_sql})") 

答对了! 邦戈!

适用于Rails 3.1