rails search form - searching multiple attributes

Rails Search Form – searching multiple attributes with one search bar

On the custom CRM I built users could originally search for clients or prospects by searching for the company name or the website. When I first created this ability I had two search forms (one for company name and one for website) side by side, along with the ability to view all companies in the database based on the company category. This looked a bit cluttered, and felt clumsy and not at all user-friendly. So let’s fix this by making it so users can search multiple attributes with one search bar.

Backstory – How my application originally worked

Originally I had two rails search forms side by side, each inside of panel (I use Bootstrap) with instructions above each rails search form. Both rails search forms were rendered as a partial on my index view, and (depending on which search form a user used) a parameter would be passed to my Companies Controller and instruct the index action which companies to include in the @companies array. My Company Name rails search form was coded to pass the query with a [:q] parameter whereas the search form for web address searches would pass it through the controller as a [:w] parameter. Since I use Heroku for my production environment, I have to use a PostgreSQL database. Finally, to make my search case-insensitive I use ILIKE and we use the % sign before and after our parameters to search the entire string for matches of 0 or more characters:

app/views/companies/_searchbars.html.erb
<div class="container-fluid">
  <div class="row">
    <div class="col-xs-6">
      <div class="panel panel-primary">
        <div class="panel-heading"><strong>Search by Company Name</strong></div>
        <div class="panel-body">Type part of the company name and search
          <div class="form-inline">
            <%= form_tag(companies_path, :method => "get", id: "search-form", :html => {class: "form"}) do %>
              <div class="form-group">
                <%= text_field_tag :q, params[:q], placeholder: "Company Name", class: "form-control" %>
              </div>
              <%= submit_tag "Search", class: 'btn btn-primary' %>
            <% end %>
          </div>
        </div>
      </div>
    </div>
    <div class="col-xs-6">
      <div class="panel panel-primary">
        <div class="panel-heading"><strong>Search by Company Website</strong></div>
        <div class="panel-body">Type part of the website address <strong>without the www. or http</strong>
          <div class="form-inline">
            <%= form_tag(companies_path, :method => "get", id: "search-form", :html => {class: "form"}) do %>
              <div class="form-group">
                <%= text_field_tag :w, params[:w], placeholder: "Company Website", class: "form-control" %>
              </div>
              <%= submit_tag "Search", class: 'btn btn-primary' %>
            <% end %>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

More Backstory (yay?!): How my controller worked

Next, my CompaniesController would receive the search query with the approprite parameter and determine which companies should be included in the @companies array to be displayed on the index view. If no search parameter is specified then it will simply display every company in the system. Below this we’ll include instructions for if a search parameter is specified:

app/controllers/companies_controller.rb
def index
  @companies = Company.all.order('LOWER(name)')
  if params[:q]
    @companies = Company.where("name ILIKE ?", "%#{params[:q]}%").all.order('LOWER(name)')
  elsif params[:w]
    @companies = Company.where("adress ILIKE ?", "%#{params[:w]%").all.order('LOWER(name)')
  end
end

And in return our app/views/companies/index.html.erb will update to show the appropriate companies.

Getting started: Fixing our controller so we can search multiple attributes with one rails search form

We’ll need to fix our CompaniesController so that with one parameter we can search multiple attributes in our Company class and have all of the results placed into our @companies array. We’ll just alter the code for when our index receives the [:q] parameter but make it search both our Company.name (where we store the company name information for each Company instance) and Company.address (where we store the website address for each Company instance). If it find a match in either column, that company should be added to our @companies array:

app/controllers/companies_controller.rb
def index
  @companies = Company.all.order('LOWER(name)')
  if params[:q]
    @companies = Company.where("name ILIKE ? OR address ILIKE ?", "%#{params[:q]}%", "%#{params[:q]}%").all.order('LOWER(name)')
  end
end

Finishing Up (already!): Fixing our Search Bar Partial

Now we just need to edit our _searchbars.html.erb so that we only have one search bar that can search multiple attributes, instead of our previous two:

app/views/companies/_searchbars.html.erb
<div class="container-fluid">
  <div class="row">
    <div class="col-xs-12">
      <div class="panel panel-primary">
        <div class="panel-heading"><strong>Search by Company Name or Website</strong></div>
        <div class="panel-body"> Type part of the company name or website <strong>without the www.</strong>
          <div class="form-inline">
            <%= form_tag(clients_path, :method => "get", id: "search-form", :html => {class: "form"}) do %>
            <div class="form-group">
              <%= text_field_tag :q, params[:q], placeholder: "Company Name or Website", class: "form-control" %>
            </div>
            <%= submit_tag "Search", class: 'btn btn-primary' %>
            <% end %>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Now we’ll just have one rails search form that will search for partial matches in the name and address columns of our Companies table.rails search form - advanced - search multiple attributes

 

Loading Facebook Comments ...

Leave a Reply

Your email address will not be published. Required fields are marked *