views:

583

answers:

4

I have an index action in rails that can handle quite a few params eg:

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

When finding users I would like to AND all the conditions that are not nil. This gives me 8 permutations of the find conditions.

How can I can I keep my code DRY and flexible and not end up with a bunch of if statements just to build the conditions for the find. Keep in mind that if no conditions are specified I just want to return User.all

+2  A: 

How about something like:

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
James Healy
Oddly enough my params hash does not seem to have an only method
Sam Saffron
+1  A: 

This seems to work quite nicely:

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

You could try Ambition, or a number of other ActiveRecord extensions.

François Beausoleil
A: 

I would normally use named scopes for something like this:

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

That's what I normally do.

François Beausoleil