ruby-on-rails - 带有可选参数的 Rails Search?

标签 ruby-on-rails ruby activerecord

当搜索可以提供许多可选参数(如 ID、邮政编码、城市和州)时,我将如何在数据库上进行搜索?这些可以有值或完全空白。我将如何进行这样的 Rails 查询?

最佳答案

通常的建议是将逻辑转移到模型中并使 Controller 尽可能精简。 filter方法有不同的做法,第一种:

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

第二种方法,编写一个仅使用现有作用域的裸过滤器:

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,过滤器方法的语法是:

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

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

class RecordsController < ApplicationController::Base
  respond_to :html, :xml

  def index
    @records = Record.filter(params)
  end
end

关于ruby-on-rails - 带有可选参数的 Rails Search?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4480088/

相关文章:

ruby-on-rails - 用:name代替:id url参数的Rails路由

ruby-on-rails - Rails 3.1 可安装引擎 : Assets (Images) not copied to the host application?

Ruby Net::HTTP 超时

ruby-on-rails - 在 Rails 3.2 中从数组调用 ActiveRecord 关联方法

php - Codeigniter Active Record - 选择字符串作为列

ruby-on-rails - 使用关联的 Rails 模型创建 gem

javascript - 创建可在远程站点上使用的非常简单的小部件的最简单方法是什么?

ruby-on-rails - 如何使用键盘进入运行 Rails 应用程序的 ruby​​-debug?

ruby-on-rails - 单表继承ActiveRecord多态关联真的有必要重写 `*_type=`方法吗?

ruby-on-rails - rails : Sidekiq unknown driver