in Railscasts, Uncategorized

Railscast 037 Simple Search Form

The GitHub Repo

The Heroku App

Form

<%= form_tag projects_path, method: :get do %>
<p>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag 'Search', name: nil %>
</p>
<% end %>

The form for the search form has many lessons to learn. The use of form_tag over form_for is preferred we are not updating attributes associated with a specific model. Here the form_tag submits to the projects path. Normally when you submit a form using the form_for or form_tag Rails helper Rails create the html tags with a post method filled in. When you submit a post request to the projects path, Rails thinks you are trying to create a new record because of the RESTful design. To counteract this you have to explicitly specify the method used on this form, in this case get.

Controller

def index
  @projects = Project.search(params[:search])
end

Instead of the usual Project.all, we use a search method that we defined in the project model. The search method accepts a argument that is matched with records in the database.

Model

class Project < ActiveRecord::Base
  def self.search(search)
    if search
      if Rails.env.development?
        where("name LIKE ?", "%#{search}%")
      elsif Rails.env.production?
        where("name ILIKE ?", "%#{search}%")
      end
    else
      all
    end
  end
end

This is where most of the work is being done. Here we are defining a class method called search which accepts one parameter. If this parameter is true, then it will search for a name similar to the search argument. There is a conditional based on the environment because the LIKE function in SQLite3 used in development is case insensitive, while the LIKE function in PostgreSQL used in Production is case sensitive. PostgreSQL LIKE To counteract this, I have included the ILIKE function for only the production environment.

The "%#{search}%" confused me, so I asked on StackOverflow about what the % was. Apparently it is SQL Wildcards used to match characters in a string. It is similar to how Regex pattern matches, but SQL Wildcards are much simpler. It appears there are only four syntaxes that can be used. %, _, [], [^]. The % substitute zero or more characters. _ substitutes a single character. [] matches sets or ranges of characters. Example: [abc]% matches anything that starts with abc. Similar to regex you use ^ to declared not. [abc]% matches anything that does NOT start with abc. Similar to Regex, so this was not too mind blowing. The tricky part was learning the syntax used.