2017-09-08 8 views
1

助けてください!インスタンスの状態でhas_manyインスタンスをクエリする方法はありません。

以下のクエリ句を1つにまとめる必要があります。句のjoins(:bar)は、bar_id IS NULLレコードがフィルタリングされます

Foo.where('bar_id IS NULL') 
Foo.joins(:bar).where('bar.daily_budget > bar.daily_cost') 

このように組み合わせるのは簡単ではありませんが、このbar_id IS NULLはフィルタリングされます。私はFooの結果結果は、より多くのような

bar_id is null or (bar_id is not null AND bars.daily_budget > bars.daily_cost) 

で欲しい

Foo.joins(:bar).where('bar.daily_budget > bar.daily_cost').where('bar_id IS NULL') 

はbar_idを持っている必要がnullで、かつbars.daily_budget> bars.daily_costバーは時間が同時に存在する場合。

答えて

1

あなたが実際に望むのはSQL UNIONです。

#orクエリメソッドを使用できます。トリックは、の両端にjoins(:bar)を使用する必要があります。関係を#に渡すか、構造的に互換性がある必要があります。

Foo.joins(:bar).where(:bar_id => nil) 
       .or(Foo.join(:bar).where('bar.daily_budget > bar.daily_cost')) 
# SELECT `foos`.* FROM `foos` INNER JOIN `bar` on `foos.bar_id` = `bar.id` WHERE(`foos`.`bar_id` is NULL OR bar.daily_budget > bar.daily_cost) 

:QueryMethod orはRailsの5

更新に追加されました:DanneManneは答えとしては、上記動作しません.joins(:bar).where(:bar_id => nil)が実際にINNER JOINをに何も与えないだろうからです。必要なのは、LEFT JOINをすることによって行うことができている:

Foo.left_outer_joins(:bar).where('foo.bar_id is null or bar.daily_budget > bar.daily_cost') 
SELECT `foos`.* from `foos` LEFT OUTER JOIN `bar` ON `foos`.`bar_id` = `bar`.`id` WHERE (foo.bar_id is null or bar.daily_budget > bar.daily_cost) 
+0

しかし 'Foo.joinsです(:バー).where(bar_id:NIL)'互換性がありません。 'where(:bar_id => nil)'の結果はフィルタリングされます。 コンソールで 'Foo.where(bar_id:nil).or(Foo.joins(:bar).where( 'bar.daily_budget> bar.daily_cost'))'を実行しようとしましたが、それらのエラーが発生しました。 'ArgumentError:Relation passed構造的に適合していなければならない。互換性のない値:[:joins] '。 – lululala

+0

'Foo.left_outer_joins(:bar).where( 'foo.bar_idはnullまたはbar.daily_budget> bar.daily_cost')' – kiddorails

1

.joins(:bar)を呼び出すことに伴う問題は、それがデフォルトでINNER JOINデータベースクエリを作成することです。その場合、bar_idがnullのレコードは結果に含まれません。 where(bar_id: null)と指定してもそれは変わりません。

ただし、記号の代わりにLEFT OUTER JOIN文字列をjoinsメソッドに渡して、この問題を回避することができます。例:

Foo.joins('LEFT OUTER JOIN bar ON foo.bar_id = bar.id') 
    .where('foo.bar_id IS NULL OR bar.daily_budget > bar.daily_cost') 

ケース内のテーブル名はおそらく複数の可能性があるので、クエリが環境に一致することを確認してください。 Railsの中

+0

「LEFT OUTER JOIN」に感謝します。しかし、@kiddorailsの答えはより短い 'Foo.left_outer_joins(:bar)'です。 – lululala

0

joinsはあなたが必要なものINNER JOIN あるOUTER JOIN

関連する問題