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.