Rails用可选参数搜索?

当搜索可以提供许多可选参数(如ID,Zip,City和State)时,如何在数据库上进行搜索? 这些可以具有值或完全空白。 我该怎么做这样的rails查询?

通常的建议是将逻辑移至模型并使控制器尽可能精益。 过滤方法有不同的方法,第一种方法:

class Record < ActiveRecord::Base def self.filter(attributes) attributes.select { |k, v| v.present? }.reduce(all) do |scope, (key, value)| case key.to_sym when :id, :zip # direct search scope.where(key => value) when :city, :state # regexp search scope.where(["#{key} ILIKE ?", "%#{value}%"]) when :order # order=field-(ASC|DESC) attribute, order = value.split("-") scope.order("#{self.table_name}.#{attribute} #{order}") else # unknown key (do nothing or raise error, as you prefer to) scope end end end end 

第二种方法,编写仅使用现有范围的裸filter

 class Record < ActiveRecord::Base SUPPORTED_FILTERS = [:id, :city, ...] scope :id, ->(value) { where(id: value) } scope :city, ->(value) { where(city: "%#{value}%") } ... def self.filter(attributes) attributes.slice(*SUPPORTED_FILTERS).reduce(all) do |scope, (key, value)| value.present? ? scope.send(key, value) : scope end end end 

对于现在使用ActionController :: Parameters的Rails 5,filter方法的语法是:

 def self.filter(attributes) attributes.permit(SUPPORTED_FILTERS).to_hash.reduce(all) do |scope, (key, value)| value.present? ? scope.send(key, value) : scope end end 

可以从应用程序的任何位置调用模型,因此它们可重复使用且更易于测试。 现在控制器看起来很简单:

 class RecordsController < ApplicationController::Base respond_to :html, :xml def index @records = Record.filter(params) end end 

您可以构建查询:

 conditions = {} conditions[:city] = city unless city.blank? conditions[:zip] = zip unless zip.blank? conditions[:state] = state unless state.blank? Address.find(:all, :conditions => conditions) 

http://metautonomo.us/projects/metasearch/就是您所需要的。

 = text_field_tag 'search[city_like]', '' = text_field_tag 'search[zip_equals]', '' = text_field_tag 'search[state_equals]', '' 

然后就是

 Record.search(params[:search])