带可选参数的 Rails 搜索? [英] Rails Search with optional parameters?

查看:24
本文介绍了带可选参数的 Rails 搜索?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当搜索可以提供许多可选参数(例如 ID、邮编、城市和州)时,我将如何对数据库进行搜索?这些可以有值或完全为空.我将如何进行这样的 rails 查询?

How would I do a search on a database when the search can provide many optional parameters such as ID, Zip, City, and State? These can either have values or be blank entirely. How would I make a rails query like that?

推荐答案

通常的建议是将逻辑移到模型中,并使控制器尽可能精简.过滤方法有多种方法,第一种:

The usual advice is to move logic to the model and keep the controller as lean as possible. There are different approaches for the filter method, the first one:

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:

A second approach, write a bare filter that only uses existing scopes:

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

For Rails 5, which now uses ActionController::Parameters, the syntax for the filter method is:

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

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

Models can be called from anywhere in your app, so they are re-usable and easier to test. Now the controller looks as simple as:

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

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

这篇关于带可选参数的 Rails 搜索?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆