Build a Simple Search with the simple_form Gem in Rails 5

Maria Schuessler
Jan 17 · 5 min read

Searching in Rails 5 is one of those things that always starts out simple “oh, I’ll just add a search bar to the site” and eventually ends up in a slew of PostgreSQL queries, tears, and eventually.. defeat. A search can be a basic filter of your model, but creating a search that is efficient, fast, and actually gets the results you want to show is much more complex. Think of how you felt last time you searched for something on Bing instead of Google. A good algorithm can make all the difference.

I’ve seen many search tutorials for Rails 5 that use form_tag , HTML forms, or form_for, but there are not as many resources for simple_form, even though simple_form has become the gold standard of Rails forms. Besides, both form_for and form_tag are on their way to be deprecated after Rails 5.2 and replaced by form_with.

Here’s a quick overview of how you can add basic search functionality to your app using the simple_form gem!

Let’s get started!

1. Setup your Rails App

I’m creating a basic rails application, without Webpacker, but using PostgreSQL as my database, because it will allow me to do case-insensitive search later on.

rails new simple_search --database=postgresql 
rails db:create

p.s. Remember to create the database after you make your rails app because postgres doesn’t create a db by default

gem 'simple_form'
gem 'bootstrap', '~> 4.2.1'
bundle install

p.s. Don’t forget the extra steps to setup Bootstrap & configure SimpleForm!

2. Create the model

For this case, I’m going to create a simple one-model app to search through a list of cocktails that I added to my database via a JSON endpoint (thanks to for the db!). I’ll go through the data import quickly. If you want a full article on seeding from a third party database, leave a message below!

First create the model with three attributes:

rails g model cocktail name glass preparation:text
rails db:migrate

Then add the seeds:

#db/seeds.rbrequire 'json'
require 'open-uri'
url = ""
Cocktail.delete_all if Rails.env.development?cocktails = JSON.parse(open(url).read)cocktails.each do |cocktail|
Cocktail.create!(name: cocktail["name"], glass: cocktail["glass"], preparation: cocktail["preparation"])

3. Create the controller & views

Next we’re adding a controller with a single action, to show a list of all the cocktails. Since our app has one page, I’m going to root the application to the cocktails index. There is no /cocktails path in the application.

First, create the controller:

rails g controller cocktails index
class CocktailsController < ApplicationController
def index
@cocktails = Cocktail.all

Then, add a home route for the index:

root to: "cocktails#index"

Lastly, let’s add a simple front-end for the cocktail:

<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-8 offset-sm-2">
<% @cocktails.each do |cocktail| %>
<h3><%= %></h3>
<p><%= cocktail.preparation %></p>
<% end %>

4. Add the search form

Now it’s time to add the search functionality. I love simple_form because of.. well… its simplicity, because you can make a form in just four lines. Check out the full documentation here.

<%= simple_form_for :search, url: root_path, method: "GET", html: { class: 'form-inline' } do |f| %>
<%= f.input :name, input_html: {value: ""} %>
<%= f.submit "Search", class: "btn btn-primary" %>
<% end %>

There’s a few things to watch out for here.

  1. The first thing is the :search . Typically, we create the form for an instance variable when manipulating a model (i.e. @cocktail) ). If I try to call the parameter @search, the application will tell me that the variable is undefined. By setting it as a symbol with the colon before :search, I can use it as a key in my params hash.

5. Query your search in the controller

We’ll start with a super simple search — an exact keyword. This is a basic query, but not really useful, because it won’t find Margarita if my search phrase is margarita, or any part of the word.

But for now, let’s start with the basics:

class CocktailsController < ApplicationController
def index
@cocktails = Cocktail.all
@search = params["search"]
if @search.present?
@name = @search["name"]
@cocktails = Cocktail.where(name: @name)
The crappy search, in action

6. Let’s make this search better!

The first thing I want to do is make my search case-insensitive, so Margarita and margarita return the same result.

Here, my simple active record query won’t do and I’ll need to add SQL. One of the reasons I started the app with PostgreSQL as my db adapter is to use ILIKE, which will give me the case-insensitive match:

@cocktails = Cocktail.where("name ILIKE ?", @name)

What about a partial search? What if we want Margarita to return all margarita recipes like Passionfruit Margarita or Strawberry Margarita? We’ll need to add wildcard rules to make that work. Note that to add the % wildcard symbol, I need to interpolate my variable as a string.

@cocktails = Cocktail.where("name ILIKE ?", "%#{@name}%")
Tada! The working search

8. That’s it!

We’re done with our basic search. There’s lots of things I can add to this app, like searching through multiple columns, multiple tables, saving my search in the session, or using scopes to make the search more efficient. Let me know below if you’d like an article on advanced search!

GitHub Repository here.

Heroku Demo here.

Further Resources:

Huge thank you to @dp_engel for the editing help~ 🤓

More Rails:

Simplify your front-end with BeautifyRuby and Rails 5

More Articles:

Time Management Techniques for Digital Nomads

Le Wagon

Stories from our community on coding, product and entrepreneurship.

Thanks to Dan Engel

Maria Schuessler

Written by

Full-Stack Developer \\ Traveler \\ Hot Sauce Entrepreneur \\ Le Wagon Mentor \\ Shanghai-based \\

Le Wagon

Le Wagon

Stories from our community on coding, product and entrepreneurship.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade