[英]Rails how to query has_many instance in condition of the instance not exist
請幫忙!
我需要將以下查詢子句合並為一個。
Foo.where('bar_id IS NULL')
Foo.joins(:bar).where('bar.daily_budget > bar.daily_cost')
當joins(:bar)
in子句時, bar_id IS NULL
記錄將被過濾。
像下面這樣組合起來並不是那么簡單,此bar_id IS NULL
將被過濾。
Foo.joins(:bar).where('bar.daily_budget > bar.daily_cost').where('bar_id IS NULL')
我想要的結果更像
bar_id is null or (bar_id is not null AND bars.daily_budget > bars.daily_cost)
Foo結果需要bar_id為null,並且bar.daily_budget> bars.daily_cost如果bar同時存在。
您真正想要的是SQL UNION。
您可以使用#or
查詢方法。 竅門是,您必須在兩端都使用joins(:bar)
才能將Relation傳遞給#,或者必須在結構上兼容。
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)
調用.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')
請注意,您的情況下的表名很可能是復數形式,因此請確保查詢與您的環境匹配。
joins
Rails是INNER JOIN
您需要的是OUTER JOIN
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.