我在rails中有一个索引动作可以处理很多参数,例如:
params[:first_name] # can be nil or first_name
params[:age] # can be nil or age
params[:country] # can be nil or country
在找到用户时,我想和所有不是零的条件。这给了我8个查找条件的排列。
我怎样才能保持我的代码DRY和灵活性,而不是为了构建查找条件而最终得到一堆if
语句。请记住,如果没有指定条件,我只想返回User.all
答案 0 :(得分:3)
如下:
conditions = params.only(:first_name, :age, :country)
conditions = conditions.delete_if {|key, value| value.blank?}
if conditions.empty?
User.all
else
User.all(:conditions => conditions)
end
答案 1 :(得分:3)
我通常会将命名范围用于这样的事情:
class User < ActiveRecord::Base
named_scope :name_like, lambda {|name| {:conditions => ["first_name LIKE ?", "#{name}%"]}}
named_scope :age, lambda {|age| {:conditions => {:age => age}}}
named_scope :in_country, lambda {|country| {:conditions => {:country => country}}}
end
class UsersController < ActionController
def index
root = User
root = root.name_like(params[:first_name]) unless params[:first_name].blank?
root = root.age(params[:age]) unless params[:age].blank?
root = root.country(params[:country]) unless params[:age].blank?
@users = root.paginate(params[:page], :order => "first_name")
end
end
这就是我通常做的事情。
答案 2 :(得分:1)
这看起来效果很好:
conditions = params.slice(:first_name, :age, :country)
hash = conditions.empty? ? {} : {:conditions => conditions}
@users = User.all hash
答案 3 :(得分:1)
使用James Healy回答,我修改了在Rails 3.2中使用的代码(如果有人需要这个)。
conditions = params.slice(:first_name, :age, :country)
conditions = conditions.delete_if {|key, value| value.blank?}
@users = User.where(conditions)
答案 4 :(得分:0)
您可以尝试使用Ambition或其他一些ActiveRecord扩展程序。
答案 5 :(得分:0)
这对我也有用
conditions = params[:search] ? params[:search].keep_if{|key, value| !value.blank?} : {}
User.all(:conditions => conditions)
答案 6 :(得分:0)
如果您碰巧参与了一个古老的项目(Rails 2.x)并且非常混乱,您可以执行以下操作,以便在原始查询中添加新字段。
原始代码:
User.find(:all,
:conditions => ['first_name LIKE ? AND age=? AND country=?',
"#{name}%", age, country]
在zip_code
字段添加新的动态条件:
zip_code = params[:zip_code] # Can be blank
zip_query = "AND zip_code = ?" unless zip_code.blank?
User.find(:all,
:conditions => ['first_name LIKE ? AND age=? AND country=? #{zip_query}',
"#{name}%", age, country, zip_code].reject(&:blank?)
向reject(&:blank?)
数组添加conditions
将过滤nil
值。
注意:如果您从零开始编码或重构,其他答案要好得多。