title: Ruby on Rails: Advanced search
body: <p>I'm having trouble understanding the best way to make a advanced search form. I have had a good search on the internet, looking at some ways, but I can't get them to work, as most of the suggestions are outdated. I have asked a question already, but I think I was too specific and I wasn't able to fix my problem. I am wanting to search on different text boxes and drop down boxes with one search button.</p>
  
  <p>EDIT2:</p>
  
  <p>projects_controller:</p>
  
  <pre><code>def index
      @projects = Project.all
  
  respond_to do |format|
        format.html # index.html.erb
        format.json { render :json =&gt; @projects }
      end
    end
  
  def search
  @project_search = Project.search(params[:search]).order(sort_column + ' ' + sort_direction).paginate(:per_page =&gt; 2, :page =&gt; params[:page])
  
  
  end
  
  
  
  
    # GET /projects/1
    # GET /projects/1.json
    def show
      @project = Project.find(params[:id])
  
      respond_to do |format|
        format.html # show.html.erb
        format.json { render json: @project }
      end
    end
  
    # GET /projects/new
    # GET /projects/new.json
    def new
      @project = Project.new
  
      respond_to do |format|
        format.html # new.html.erb
        format.json { render json: @project }
      end
    end
  
    # GET /projects/1/edit
    def edit
      @project = Project.find(params[:id])
    end
  
    # POST /projects
    # POST /projects.json
    def create
  
      @project = Project.new(params[:project])
  
  
      @project.client = params[:new_client] unless params[:new_client].blank?
      @project.exception_pm = params[:new_exception_pm] unless params[:new_exception_pm].blank?
      @project.project_owner = params[:new_project_owner] unless params[:new_project_owner].blank?
      @project.role = params[:new_role] unless params[:new_role].blank?
      @project.industry = params[:new_industry] unless params[:new_industry].blank?
      @project.business_div = params[:new_business_div] unless params[:new_business_div].blank?
  
      respond_to do |format|
        if @project.save
          format.html { redirect_to @project, notice: 'Project was successfully created.' }
          format.json { render json: @project, status: :created, location: @project }
        else
          format.html { render action: "new" }
          format.json { render json: @project.errors, status: :unprocessable_entity }
        end
      end
    end
  
    # PUT /projects/1
    # PUT /projects/1.json
    def update
      @project = Project.find(params[:id])
  
      respond_to do |format|
        if @project.update_attributes(params[:project])
          format.html { redirect_to @project, notice: 'Project was successfully updated.' }
          format.json { head :no_content }
        else
          format.html { render action: "edit" }
          format.json { render json: @project.errors, status: :unprocessable_entity }
        end
      end
    end
  
    # DELETE /projects/1
    # DELETE /projects/1.json
    def destroy
      @project = Project.find(params[:id])
      @project.destroy
  
      respond_to do |format|
        format.html { redirect_to projects_url }
        format.json { head :no_content }
      end
    end
  
  
  
  
  private
  
    helper_method :sort_column, :sort_direction
    def sort_column
      Project.column_names.include?(params[:sort]) ? params[:sort] : "project_name"
    end
  
    def sort_direction
      %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
    end
  end
  </code></pre>
  
  <p>Search View:</p>
  
  <pre><code>&lt;h1&gt;Search&lt;/h1&gt;
  
  &lt;%= form_tag search_path, method: :get do %&gt;
  &lt;%= hidden_field_tag :direction, params[:direction] %&gt;
    &lt;%= hidden_field_tag :sort, params[:sort] %&gt;
    &lt;%= text_field_tag :project_name, params[:project_name] %&gt;
    &lt;%= text_field_tag :client, params[:client] %&gt;
    &lt;%= submit_tag "Search", name: nil %&gt;
  &lt;% end %&gt;
  
  
  
  &lt;table class = "pretty"&gt;
  &lt;table border="1"&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;%= sortable "project_name", "Project name" %&gt; &lt;/th&gt;
      &lt;th&gt;&lt;%= sortable "client", "Client" %&gt;&lt;/th&gt;
      &lt;th&gt;Exception pm&lt;/th&gt;
      &lt;th&gt;Project owner&lt;/th&gt;
      &lt;th&gt;Tech&lt;/th&gt;
      &lt;th&gt;Role&lt;/th&gt;
      &lt;th&gt;Industry&lt;/th&gt;
      &lt;th&gt;Financials&lt;/th&gt;
      &lt;th&gt;Business div&lt;/th&gt;
      &lt;th&gt;Status&lt;/th&gt;
      &lt;th&gt;Start date&lt;/th&gt;
      &lt;th&gt;End date&lt;/th&gt;
  &lt;% if false %&gt;
      &lt;th&gt;Entry date&lt;/th&gt;
      &lt;th&gt;Edited date&lt;/th&gt;
      &lt;th&gt;Summary&lt;/th&gt;
      &lt;th&gt;Lessons learned&lt;/tStackh&gt;
      &lt;th&gt;Customer benifits&lt;/th&gt;
      &lt;th&gt;Keywords&lt;/th&gt;
      &lt;!th&gt;&lt;/th&gt;
      &lt;!th&gt;&lt;/th&gt;
      &lt;!th&gt;&lt;/th&gt;
  &lt;% end %&gt;
    &lt;/tr&gt;
  
  &lt;% @project_search.each do |t| %&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;%= t.project_name %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.client %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.exception_pm %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.project_owner %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.tech %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.role %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.industry %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.financials %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.business_div %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.status %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.start_date %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.end_date %&gt;&lt;/td&gt;
  &lt;% if false %&gt;
      &lt;td&gt;&lt;%= t.entry_date %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.edited_date %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.summary %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.lessons_learned %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.customer_benifits %&gt;&lt;/td&gt;
      &lt;td&gt;&lt;%= t.keywords %&gt;&lt;/td&gt;
  &lt;% end %&gt;
      &lt;!td&gt;&lt;%#= link_to 'Show', project %&gt;&lt;/td&gt;
      &lt;!td&gt;&lt;%#= link_to 'Edit', edit_project_path(project) %&gt;&lt;/td&gt;
      &lt;!td&gt;&lt;%#= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;% end %&gt;
  &lt;/table&gt;
  
  &lt;br /&gt;
  &lt;%= will_paginate (@project_search) %&gt;
  
  
  &lt;%= button_to "Search Again?", search_path, :method =&gt; "get" %&gt;
  
  &lt;%# end %&gt;
  &lt;%= button_to "Home", projects_path, :method =&gt; "get" %&gt;
  </code></pre>
  
  <p>Project.rb</p>
  
  <pre><code>class Project &lt; ActiveRecord::Base
    attr_accessible :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, :exception_pm, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech
  
  validates_presence_of :business_div, :client, :customer_benifits, :end_date, :exception_pm, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech
  
  
  
  def self.search search_term
   return scoped unless search_term.present?
   where find(:all, :conditions =&gt; ['project_name OR client LIKE ?', "%#{search_term}%"])
  end
  
  end
  </code></pre>
  
  <p>Routes:</p>
  
  <pre><code>FinalApp::Application.routes.draw do
  resources :projects
  match "search" =&gt; "projects#search", :as =&gt; :search
  root :to =&gt; 'projects#index'
  end
  </code></pre>
  
  <p>As you can see, I'm still a fair bit away from having a finished application. I am trying to make a search form that will be able to search on the following fields: Project name, Client, ID, Industry, Role, Technology, Project Owner, Status, Start Date, End Date, and Keywords. The search form would have either text boxes or drop down menus depending on which field the user was searching for. I am wanting to chain each field and search on them all in one go. Before, I was only using project_name, and client as examples to make it easier for you to understand my code. Hopefully you can see now what I am trying to do.</p>