Search Feature using Postgres 9.6.2 and Rails 5.1

In this article, you will learn how to implement search feature using pg_search gem in Rails 5.1 and Postgresql 9.6.2.

Install Postgres on Mac OS

I am on Mac OS 10.10.5, to install Postgres:

brew install postgres

To run postgres as a service install services:

brew tap homebrew/services

You can start the postgres server:

brew services start postgresql

To stop:

brew services stop postgresql

To restart:

brew services restart postgresql

Install the pg gem:

gem install pg -- --with-pg-config=/usr/local/bin/pg_config

To check the Postgres version:

pg_config --version

Search Feature using pg_search Gem

Create a new Rails 5.1 project.

rails new acomp --database=postgresql

Add the dotenv-rails gem to the development group in the Gemfile.

gem 'dotenv-rails'

Run bundle.

Create .env file in the Rails app root directory and specify the database user name and password.

PG_USER: 'db user'
PG_PASS: 'db password'

Add .env file to the .gitignore file so that it does not get checked in to git. Change the database.yml to use these environment variables for user and password.

  adapter: postgresql
  encoding: unicode
  database: myapp_dev
  pool: 5
  username: <%= ENV['PG_USER'] %>
  password: <%= ENV['PG_PASS'] %>

  adapter: postgresql
  encoding: unicode
  database: myapp_test
  pool: 5
  username: test

Create a user model:

rails g model user name surname

Migrate the database.

rails db:migrate

Add faker gem to the development group of the Gemfile.

gem 'faker'

Run bundle to install the gem. In the seeds.rb we can use the faker gem to populate the database with some records.

50.times do
  User.create({name: Faker::Name.first_name,
              surname: Faker::Name.last_name})

Populate the database:

rails db:seed

Define the routes:

resources :users, only: [:index]
root to: 'users#index'

Generate a users controller with index action:

rails g controller users index

Implement the index action:

class UsersController < ApplicationController
  def index
    @users = User.all

The index page:

  <%= render @users %>

Create the user partial:

  <%= %> <%= user.surname %>

Let's add the search form to the users index page:

<%= form_tag users_path, method: :get do %>
  <%= text_field_tag 'term', params[:term], placeholder: "Enter user's name or surname" %>
  <%= submit_tag 'Search' %>
<% end %>

Add the pg_search gem to Gemfile.

gem 'pg_search'

Run bundle.

Add the search method to the user model:

include PgSearch
pg_search_scope :search_by_full_name, against: [:name, :surname]

Change the users index action:

@users = if params[:term]

The search will now work. To implement partial search, change the user model:

pg_search_scope :search_by_full_name, against: [:name, :surname],
    using: {
      tsearch: {
        prefix: true

Now you search users by providing part of their name or surname.

Match Multiple Words

pg_search_scope :search_by_full_name, against: :name, using: { tsearch: { any_word: true } }

Search for all records that contains the term (separated by spaces) in the first name.


pg_search_scope :search_by_full_name, against: { name: 'A', surname: 'B' }

Rank first name higher than surname in the search results. You can download the source code for this article from sgres.


Related Articles

Watch this Article as Screencast

You can watch this as a screencast Search Feature using Postgres 9.6.2 and Rails 5.1

Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.