2011-04-01 35 views
12

我有一個Rails 3作用域,它排除了一個ID數組。Rails作用域對NOT IN值什麼都不做

什麼是最好的方式來編寫範圍,以便它在數組爲空並且仍然可鏈接時不執行任何操作?我現在有這一點,它的工作原理,但似乎有點做作:

scope :excluding_ids, 
     lambda {|ids| ids.empty? ? relation : where('id not in (?)', ids) } 

如果我沒有「ids.empty關係:??」位,當id爲空,生成的SQL是

... ID not in (NULL) ... 

這將永遠不會返回。所以像這樣:

Model.excluding_ids([]).where('id > 0') 

返回沒有結果。

回答

19

如果ids數組爲空,則不會返回任何東西。

scope :excluding_ids, lambda { |ids| 
    where(['id NOT IN (?)', ids]) if ids.any? 
} 

如果沒有ids,查詢將在沒有任何附加約束的情況下運行。

+0

不客氣。 – 2011-04-01 22:24:26

+0

感謝您的編輯。 (刪除我之前的評論,因爲我現在無法編輯它,所以出現錯誤) – tee 2011-04-01 22:35:25

+0

啊,好多了!我給你的答案一個獨角獸。 – 2011-04-01 22:44:35

0

以下情況如何? (它仍檢查空數組雖然,所以如果這是你想避開它不是多大的改善:)

scope :excluding_ids, 
    lambda {|ids| (ids.empty? && relation) || where('id not in (?)', ids) } 
3

這是道格拉斯答案的一個小小的變化,使用ruby 1.9 stabby lambda語法,並且在where方法中沒有括號。

scope :excluding_ids, ->(ids) {where("id NOT IN (?)", ids) if ids.any?} 
7

在Rails 4,你可以使用:

scope :excluding_ids, ->(ids) { where.not(id: ids) } 
+1

你是不是指「... - >(ids){where.not(id:ids)}」?請參閱:http://edgeguides.rubyonrails.org/active_record_querying.html#passing-in-arguments – 2016-01-12 08:26:14

+1

是的,答案已更新! – GuiGS 2016-01-12 18:43:47