Back in October 2005, I wrote an article entitled Building the SQL WHERE Clause Dynamically. This article is obsolete and I’m replacing it with this one instead.
What do you do with a FORM that has multiple conditions? Something like this:
The way I would do it today is using named scopes:
app/models/person.rb
1 class Person < ActiveRecord::Base
2 is_taggable
3
4 named_scope :in_region,
5 lambda {|region| {:conditions => {:region => region}}}
6 named_scope :with_salary,
7 lambda {|lower, upper| {:conditions =>
8 {:salary => (lower .. upper)}}}
9
10 # Elided, but something similar to the above
11 named_scope :tagged_with,
12 lambda {|tags| {:conditions =>
13 …}}
14 end
Then you need your controller to translate between what the view provides and what the model expects:
app/controllers/searches_controller.rb
1 class SearchesController < ApplicationController
2 def show
3 root = Person
4 root = root.in_region(params[:region]) unless params[:region] =~ /all/i
5 unless params[:salary] =~ /all/i
6 params[:salary].gsub!("K", "000")
7 lower, upper = params[:salary].split("-")
8 root = root.with_salary(lower, upper)
9 end
10 root = root.tagged_with(Tag.parse(params[:tags])) unless params[:tags].blank?
11 @people = root.paginate(:page => params[:page])
12 end
13 end
For simpler forms, the approach above would be sufficient. For more complex forms, I suggest you look at plugins that aim to provide more structure around your SQL clauses, such as:
I also suggest looking at Searching and Queries Plugins – Agile Web Development to find other plugins.