按标题,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])
答案 0 :(得分: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 :(得分:1)
您可以非常轻松地链接where
条款。
@results = Model.all
@results = @results.where('country_translations.title ILIKE ?', "%#{search[:title]}%") if search[:title].present?
如果您正在使用Postgres,您还可以使用正则表达式而不是ILIKE来删除此%#{}%
内容。
@results = @results.where('country_translations.title ~* ?', search[:title]) if search[:title].present?
以及其他领域。
答案 2 :(得分:1)
这实际上取决于你想如何处理它。
首先,我将查询分解为多个where
,默认为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.
答案 3 :(得分: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])