2017-06-21 124 views
0

按標題,created_at日期過濾項目,但其中一個項目將爲空,並引發錯誤,我該如何處理?通過多個字段過濾項目

where("country_translations.title ILIKE ? AND country_translations.created_at > ? AND country_translations.created_at < ?", "%#{search[:title]}%", search[:created_at_gt], search[:created_at_lt]) 

回答

1

你可以做這樣的事情:

YourModel.where(filter_by_translations_title).where(filter_by_translations_created) 

def filter_by_translations_title 
    ['country_translations.title ILIKE ?', search[:title]] if search[:title].present? 
end 
#...add rest of methods here 

鏈接#where將通過AND加入所有查詢。通過這種方式,您可以根據需要添加儘可能多的子問題,並控制其行爲。

1

你可以很容易地連鎖你的where子句。

@results = Model.all 
@results = @results.where('country_translations.title ILIKE ?', "%#{search[:title]}%") if search[:title].present? 

如果你使用的是Postgres,您還可以使用正則表達式,而不是想把它擺脫這種%#{}%東西。

@results = @results.where('country_translations.title ~* ?', search[:title]) if search[:title].present? 

等您的其他領域。

1

這實際上取決於你想如何處理。

首先,我會將查詢分解爲多個where s,默認爲AND操作。這是可讀性:

Model.where("country_translations.title ILIKE ?", "%#{search[:title]}%") 
    .where("country_translations.created_at > ?", search[:created_at_gt]) 
    .where("country_translations.created_at < ?", search[:created_at_lt]) 

您既可以使用||運營商通過默認值,如:

Model.where("country_translations.title ILIKE ?", "%#{search[:title] || ''}%") 
    .where("country_translations.created_at > ?", search[:created_at_gt] || Time.now) 
    .where("country_translations.created_at < ?", search[:created_at_lt] || Time.now) 

,也可以分成有需要時僅應用於三個濾這樣的:

query = Model.all 
query = query.where("country_translations.title ILIKE ?", "%#{search[:title]}%") if search[:title] 
query = query.where("country_translations.created_at > ?", search[:created_at_gt]) if search[:created_at_gt] 
query = query.where("country_translations.created_at < ?", search[:created_at_lt]) if search[:created_at_lt] 

# query now is filtered only with present filters. 
+0

最後的選擇上不僅過濾命中分貝多次,但負載data..it'all'第一的理念輸了,然後逐漸過濾它在以前數據是沒有意義的加載,因爲它無論如何被覆蓋...設置默認值肯定是一個不錯的選擇 –

+0

@ Md.FarhanMemon居然沒有。在您讀取結果之前,它不會觸及數據庫。如果您在控制檯中運行它,它將**運行許多SQL命令,因爲控制檯正嘗試在每一行上打印結果。但是,當在腳本中運行時,.where命令會積累並創建一個SQL查詢以在需要時執行。 –

1

你可以隨時使用範圍在這種情況下,他們來得心應手,幾乎無處不

scope :filter_by_title, -> (title) { where('title ILIKE ?', "%#{title}%") if title.present? } 
scope :filter_by_created_at_lt, -> (date) { where('created_at < ?', date) if date.present? } 
scope :filter_by_created_at_gt, -> (date) { where('created_at > ?', date) if date.present? } 

然後你就可以重組查詢作爲

Model.filter_by_title(search[:title]) 
    .filter_by_created_at_lt(search[:created_at_lt]) 
    .filter_by_created_at_gt(search[:created_at_gt])