Advanced Model Based searches in rails

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
comments powered by Disqus