Build a Simple Search with the simple_form Gem in Rails 5

Build a Simple Search with the simple_form Gem in Rails 5

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.

Follow

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

#Gemfile
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 github.com/teijo 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.rb
require 'json'
require 'open-uri'
url = "https://raw.githubusercontent.com/maltyeva/iba-cocktails/master/recipes.json"
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"])
end

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:

#terminal 
rails g controller cocktails index
#app/controllers/cocktails_controller.rb
class CocktailsController < ApplicationController
  def index
   @cocktails = Cocktail.all
  end
end

Then, add a home route for the index:

#config/routes.rb 
root to: "cocktails#index"

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

#app/views/cocktails/index.html.erb
<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-8 offset-sm-2">
      <h1>Cocktails</h1>
      <% @cocktails.each do |cocktail| %>
        <h3><%= cocktail.name %></h3>
        <p><%= cocktail.preparation %></p>
      <% end %>
    </div>
  </div>
</div>

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.

#app/views/cocktails/index.html.erb
<%= 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.
  2. The url of the search form tells us on which page the results will be displayed. Here I specified it as the root_path. The application only has one page (the root page of the cocktails index), so I need to tell my form to show the results on that page.
  3. By default, a simple_form has the method POST. Since a search is a GET request, we need to explicitly specify that in the first line.
  4. The input :name is going to be a key inside of my params hash. The value is the keyword the user searches for. In order to reset the form on page refresh, I am giving it a default value of blank.

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)
    end
  end
end

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}%")

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 reading:

How To Use PostgreSQL with Your Ruby on Rails Application on macOS ☞ https://morioh.com/p/09f1e543c728

Ruby For Beginners: Learn to Code with Ruby from Scratch ☞ http://class.learnstartup.net/p/GgFNUm4tP

Ruby Metaprogramming Is Even Cooler Than It Sounds ☞ https://morioh.com/p/0116c0dcd0fe/

Ruby on Rails Tutorial: Learn 6 Ruby on Rails SEO Techniques ☞ http://class.learnstartup.net/p/CZBBMrl-_

Ruby Algorithm Documentation with AsciiDoc and Knitr ☞ https://morioh.com/p/b104565ecc94/

Ruby Programming for Beginners ☞ http://class.learnstartup.net/p/vjkBeGb2M

ruby-on-rails ruby

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Ruby on Rails Developer | Hire RoR Developer

#1 Ruby on Rails development company. Hire Ruby on rails developer or a team to build secure, scalable and complex web solutions with a quick turnaround time.

Explain Ruby on rails MVC

Our Ruby on Rails Training will provide you to learn about Rails and web applications development with realty. Our Ruby on Rails Course also includes live sessions.

"Rewrite your Software," says Creator of Ruby on Rails

David Heinemeier Hansson is the creator of Ruby on Rails, co-founder & CTO of Basecamp, best-selling author, Le Mans class-winning race car driver, family man, frequent podcast guest, and inspirational conference speaker.

Pros & Cons you must know before using Ruby on Rails for your startup

Click here, free ruby on rails course videos for you. It shows you best way to complete Ruby certification. OnlineITGuru guides you towards easy Web script

Ruby on Rails Performance Tuning

Synchronises Assets between Rails and S3. Contribute to AssetSync/asset_sync development by creating an account on GitHub.