The*_*y15 23 ruby activerecord ruby-on-rails
当搜索可以提供许多可选参数(如ID,Zip,City和State)时,如何在数据库上进行搜索?这些可以具有值或完全空白.我将如何进行类似的rails查询?
tok*_*and 32
通常的建议是将逻辑移动到模型并使控制器尽可能精益.过滤方法有不同的方法,第一种方法:
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
Run Code Online (Sandbox Code Playgroud)
第二种方法,写一个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
Run Code Online (Sandbox Code Playgroud)
对于现在使用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
Run Code Online (Sandbox Code Playgroud)
可以从应用程序的任何位置调用模型,因此它们可重复使用且更易于测试.现在控制器看起来很简单:
class RecordsController < ApplicationController::Base
respond_to :html, :xml
def index
@records = Record.filter(params)
end
end
Run Code Online (Sandbox Code Playgroud)
Pan*_*kos 17
您可以构建查询:
conditions = {}
conditions[:city] = city unless city.blank?
conditions[:zip] = zip unless zip.blank?
conditions[:state] = state unless state.blank?
Address.find(:all, :conditions => conditions)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8505 次 |
| 最近记录: |