After watching a railscast episode on advanced searching I thought I would give it a try. So I came up with a slightly modified version that would handle my search.
Model
class ExportSearch
def timecards
find_cards
end
def users(u)
@u = u
end
def projects(p)
@p = p
end
def tasks(t)
@t = t
end
def dates(date1, date2)
@d1 = date1
@d2 = date2
end
def clients(c)
@c = c
end
private
def find_cards
TimeCard.find(:all, :conditions => conditions, :include => {:task => :project}, :order => :date)
end
def projects_conditions
["tasks.project_id IN (?)", @p] unless @p.blank?
end
def client_conditions
["projects.client_id IN (?)", @c] unless @c.blank?
end
def date_conditions
["date BETWEEN ? AND ?", @d1, @d2] unless (@d1.blank? || @d2.blank?)
end
def task_conditions
["task_id IN (?)", @t] unless @t.blank?
end
def users_conditions
["user_id IN (?)", @u] unless @u.blank?
end
def conditions
[conditions_clauses.join(' AND '), *conditions_options]
end
def conditions_clauses
conditions_parts.map { |condition| condition.first }
end
def conditions_options
conditions_parts.map { |condition| condition[1..-1] }.flatten
end
def conditions_parts
private_methods(false).grep(/_conditions$/).map { |m| send(m) }.compact
end
end
Controller
search = ExportSearch.new
search.users(params[:export][:users].join(',')) unless params[:export][:users].blank?
search.tasks(params[:export][:tasks].join(',')) unless params[:export][:tasks].blank?
search.projects(params[:export][:projects].join(',')) unless params[:export][:projects].blank?
search.dates(start_date, end_date)
@time_cards = search.timecards