Find by multiple optional fields

My application has several search fields. Each field is optional and
if they are all left blank, I return some reasonable results. If the
fields were simply conditional I could add each search term to a hash
then pass that hash as conditions, like so:

conditions = {}
conditions[:a] = 1 if params[:a] == 1
conditions[:b] = 1 if params[:b] == 1

Task.find(:all, :conditions => conditions.empty? ? nil : conditions)

The problem is that some of the search terms aren’t that simple. One
is a date field another is a name so I want to perform a find such as:

Task.find(:all, :conditions => [‘start >= ?’, params[:date]])
Task.find(:all, :conditions => [‘name LIKE ?’, “%#{params[:name]}%”])

…but I also want to include the conditions hash if there are simple
comparison fields. I’d also like to potentially combine the two
conditions above. How to creating a conditions array with multiple
optional conditions isn’t obvious (to me at least). What I’m doing as
a workaround is nesting the conditions has inside a with_scope for
each kind of “special” (not simple hash’able conditions) but it’s not
DRY and it’s not clean.

Is there a way to use both a conditions hash and array with a find?
Or is there a way to create a “>=” or “LIKE” condition using a hash?

  • Peter

ptb wrote:

The problem is that some of the search terms aren’t that simple. One
is a date field another is a name so I want to perform a find such as:

Task.find(:all, :conditions => [‘start >= ?’, params[:date]])
Task.find(:all, :conditions => [‘name LIKE ?’, “%#{params[:name]}%”])

There are a few model plugins which can help with creating queries. One
that I use is squirrel:

which I find works extremely well.