2016-04-25 103 views
1

我想運行在Rails中添加一個作用域,只有當參數傳入它時,纔有效 - 有沒有一種簡潔的方式來避免混亂1=1默認參數?紅寶石範圍/ ActiveRecord查詢無操作

scope :tagged, -> (tags) { [tags].flatten.compact.empty? ? where('1 = 1') : where("#{self.table_name}.tags @> ARRAY[?]::varchar[]", [tags].flatten.compact)} 

基本上,什麼的where('1=1')一個範圍,將返回當前的查詢,並允許繼續鏈內的相同呢?返回self不起作用 - 它返回對象,並且所有鏈需要從頭開始重新構建。

回答

3

範圍all解決了您的問題。分裂的巨大的班輪到更多的東西可讀給出:

scope :tagged, -> (tags) do 
    if [tags].flatten.compact.empty? 
    all 
    else 
    where(
     "#{self.table_name}.tags @> ARRAY[?]::varchar[]", 
     [tags].flatten.compact 
    ) 
    end 
end 

然而,這可以再往前走一步:如果軌道範圍返回nil,那麼它將隱含呼叫all反正!換句話說,我們可以簡單的寫:

scope :tagged, -> (tags) do 
    if [tags].flatten.compact.present? 
    where(
     "#{self.table_name}.tags @> ARRAY[?]::varchar[]", 
     [tags].flatten.compact 
    ) 
    end 
end 
+0

我也建議,如果可能的話,簡化了調用該範圍的代碼:您的來電'.flatten.compact'是有些冒險!理想情況下,您應該對方法之間傳遞的數據結構有更多的信心。 –

+0

'[tags] .flatten.compact'實際上非常有用 - 它允許使用'nil',一個'tag'和一個'[tags]'數組作爲範圍。更多關於靈活性而不是不信任。 –

+0

[* tags]是我的首選方法。確切地說,你說的(除了'nil'外,還允許'[]'),不再有。 –