Rails搜索多个条件(如果值不为空)

假设我有一个带有字段word_count的模型Book ,可能还有很多其他类似字段。

在数据库的“高级搜索”中将条件串在一起的好方法是什么? 在上面的例子中,我有一个搜索表单,其中包含“ word count between ___ and ___ ”框。 如果用户填写第一个框,那么我想要返回字数大于该值的所有图书; 同样,如果用户填写第二个框,那么我想要返回字数少于该值的所有书籍。 如果两个值都填入,那么我想返回该范围内的字数。

显然,如果我这样做

 Book.where(:word_count => ..) 

如果只填写其中一个字段,这将会中断。有没有办法优雅地处理这个问题? 请记住,可能存在许多类似的搜索条件,因此我不想为每种可能的组合构建单独的查询。

很抱歉,如果之前已经提出此问题,但搜索网站尚未产生任何有用的结果。

怎么样的:

 @books = Book @books = @books.where("word_count >= ?", values[0]) if values[0].present? @books = @books.where("word_count <= ?", values[1]) if values[1].present? 

ActiveRecord将链接where子句

唯一的问题是,如果值[0] &&值[1],如果值[0]大于值[1],查询将不返回任何内容。

对于我们的高级搜索,我们创建了一个filter对象,它将activerecord查询封装到简单的方法中。 它最初基于这个Thoughtbotpost

书籍filter看起来像这样:

 class BookFilter def initialize @relation = Book.scoped end def restrict(r) minimum_word_count!(r[:first]) if r[:first].present? maximum_word_count!(r[:second]) if r[:second].present? recent! if r.try(:[], :recent) == '1' @relation end protected def recent! where('created_at > ? ', 1.week.ago) end def minimum_word_count!(count) where('word_count >= ? ', count) end def maximum_word_count!(count) where('word_count <= ?', count) end def where(*a) @relation = @relation.where(*a) end end #to use books = BookFilter.new.restrict(params) 

看一下ransack gem,它是meta_search gem的inheritance者,它似乎仍然拥有更好的文档。

如果您确实想要自己滚动,那么没有什么可以阻止您使用相同的属性链接子句:

 scope = Book scope = scope.where("word_count >= ?", params[:first]) if params[:first] scope = scope.where("word_count <= ?", params[:last]) if params[:last] 

但是真的没有必要推出自己的搜索,有很多现成的解决方案,如上面的gem。