2009-07-23 12 views
5

tengo una acción de índice en rieles que puede manejar un buen número params por ejemplo:dinámico encontrar condiciones de registro activo

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

Cuando la búsqueda de los usuarios que me gustaría y todas las condiciones que no son nulas. Esto me da 8 permutaciones de las condiciones de búsqueda.

¿Cómo puedo mantener mi código SECO y flexible y no terminar con un montón de declaraciones if solo para construir las condiciones para el hallazgo. Tenga en cuenta que si no se especifican condiciones sólo quiero volver User.all

Respuesta

1

Esto parece funcionar bastante bien:

conditions = params.slice(:first_name, :age, :country) 
hash = conditions.empty? ? {} : {:conditions => conditions} 
@users = User.all hash 
3

¿Qué tal algo como:

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

Por extraño que parezca mi hash params no parece tener un único método –

0

Usted podría intentar Ambition, o varias otras extensiones de ActiveRecord.

3

que normalmente usa ámbitos nombrados para algo como esto:

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 

Eso es lo que hago normalmente.

0

Esto funciona para mí también

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

Usando respuesta James Healy, modifico el código para ser utilizado en Rails 3.2 (por si alguien por ahí que necesite este).

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

@users = User.where(conditions) 
0

Si le sucede a estar en un antiguo proyecto (rieles 2.x) y muy sucio, se puede hacer algo como lo siguiente para añadir nuevos campos a la consulta original.

Código original:

User.find(:all, 
    :conditions => ['first_name LIKE ? AND age=? AND country=?', 
     "#{name}%", age, country] 

Adición de una nueva condición dinámica en el campo 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?) 

Adición de un reject(&:blank?) a la conditions matrices filtrará el valor nil.

Nota: Las otras respuestas son mucho mejores si está codificando desde cero o refactorizando.

Cuestiones relacionadas