2017-08-08 14 views
0

サブスクリプションをRailsで使用しているときに奇妙な動作が発生しました。非サブクエリを生成するのにうまくいきますが、Railsは完全なクエリを構築するときに結合テーブルについて「忘れる」ようです。サブクエリ実行時にActiveRecordに結合テーブルがありません

ここは例です。私が使っているテーブルにあまり注意を払わないようにしてください。これは実際のクエリが実際には複雑すぎるためです。

この1つは動作します:

2.4.0 :015 > User.all.includes(:company).where(companies: {id: 0}) 
    SQL (0.5ms) SELECT `users`.`id` AS t0_r0, [..] 
    `companies`.`id` AS t1_r0, [..] 
    FROM `users` LEFT OUTER JOIN `companies` ON `companies`.`id` = 
    `users`.`company_id` WHERE `companies`.`id` = 0 ORDER BY 
    `users`.`username` ASC 
=> #<ActiveRecord::Relation []> 

をしかし、私はどこでそれをすべてをラップする場合:

2.4.0 :016 > User.where(id: User.all.includes(:company).where(
companies: {id: 0}).references(:companies)) 
    User Load (1.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` 
    IN (SELECT `users`.`id` FROM `users` WHERE `companies`.`id` = 0 ORDER 
    BY `users`.`username` ASC) ORDER BY `users`.`username` ASC 
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 
'companies.id' in 'where clause' 

は私が欠けている明白なものはありますか?または、Railsはサブクエリの結合を処理できませんか?

また、私はjoins()を使用できる位置にいません。また、結合が結果をもたらさないレコードを返す必要があるため、includes()が必要です。

私はRuby 2.4.0とRails 5.0.2を使用しています。

答えて

1

それは(ここでは、User has_many :ordersOrder belongs_to :user)このような状況であなたを買っているものincludesを使用しているように見えるので、あなたはleft_outer_joinsを使用して試みることができる:

puts Order.where({ 
    id: Order.left_outer_joins(:user).where(users: { id: [nil, 1] }) 
}).to_sql 

# SELECT "orders".* FROM "orders" 
# WHERE "orders"."id" IN (
# SELECT "orders"."id" FROM "orders" 
# LEFT OUTER JOIN "users" ON "users"."id" = "orders"."user_id" 
# WHERE ("users"."id" = 1 OR "users"."id" IS NULL) 
#) 

それが可能だ(私はちょうど今、右推測しているが) RailsはCompanyからすべての列を選択するためにはLEFT OUTER JOINSが本当に必要でしたが、条件に追加して以来、すべての列を取得する必要はなく、users.idを取得するだけです、それだけで結合をしません。

+0

それはそれを解決しました!ありがとう! – Jacotb

0

あなたは試すことができます:

User.where(id: User.joins(:company).where(companies: {id: 0}).references(:companies)) 

しかし、あなたはwhereでそれをすべてを包む必要とする理由私は理解していませんか?

私はUser.includes(:company).where(companies: {id: 0})が必要なすべてのユーザーを返すと思います。

+0

これは私の状況ではうまくいきません。なぜなら、結果が返されない「ユーザー」も返さなければならないからです。あなたの提案はそれらをすべて省略します。 私の実際のクエリでは、条件が異なるテーブルが使用されます。それはすべてプログラムの構造と関係しています。私はこの質問の目的のために簡略化しました。 – Jacotb

関連する問題