2009-07-23 7 views
5

У меня есть действие индекса в рельсах, которые могут обрабатывать довольно много PARAMS например:Динамические найти условия в активной записи

params[:first_name] # can be nil or first_name 
params[:age]  # can be nil or age 
params[:country] # can be nil or country 

При поиске пользователей я хотел бы и все условия, которые не равны нулю. Это дает мне 8 перестановок условий поиска.

Как я могу сохранить свой код СУХОЙ и гибкий, а не заканчивать кучей if инструкций, чтобы создать условия для поиска. Имейте в виду, что, если не указаны условия, я просто хочу, чтобы вернуться User.all

ответ

1

Это, кажется, работает довольно хорошо:

conditions = params.slice(:first_name, :age, :country) 
hash = conditions.empty? ? {} : {:conditions => conditions} 
@users = User.all hash 
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 
+0

Как ни странно, у моего параметра hash нет единственного метода –

0

Вы можете попробовать Ambition, или несколько других расширений ActiveRecord.

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 

Вот что я обычно делаю.

0

Это работает для меня слишком

conditions = params[:search] ? params[:search].keep_if{|key, value| !value.blank?} : {} 
User.all(:conditions => conditions) 
1

Использование Джеймс Хили ответ, я могу изменить код, который будет использоваться в Rails 3.2 (в случае, если кто-то там это нужно).

conditions = params.slice(:first_name, :age, :country) 
conditions = conditions.delete_if {|key, value| value.blank?} 

@users = User.where(conditions) 
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.

Примечание: Другие ответы намного лучше, если вы кодируете нуль или рефакторинг.

Смежные вопросы