Why a search functionality ?
Why not? why not to make life easier by adding a simple search button ? its perfectly fine if i have ten or hundreds of records. But what if i have thousands or tens of thousands of records, i or any other user would not want to waste time by searching for a particular record by going through a list of records one by one. So why not to just add a simple search functionality for that.
Adding search in rails
There are easy ways as well as complex ways to add search functionality in rails, there are also many gems that we can use for that, some of them are simple and easy to use just like the ‘ransack’ gem. While other gems provide a wide range of features like autocomplete, caching, faster indexing, etc.
Ransack Github Link : https://github.com/activerecord-hackery/ransack
How i added a simple search functionality
So, i created a basic application with a books model where i can add books and a short description about the book. Books will have a title, description and an author. I also associated the book model with an user model (although this is not required to add a search, but i like it this way).
At first i added ransack to my gemfile and ran bundler
#File: Gemfile
gem 'ransack'
In my books controller i added a search method for ransack, i wanted the search to work only in my index view so i added the following in the index method of my books controller. I also added pagination with kaminari (so i added the .per page param). After that i also had to permit those new parameters, so i added :q, :search
as permitted params in my private methods
#File: app/controllers/books_controller.rb
class BooksController < ApplicationController
def index
@search = Book.search(params[:q])
##for paginations i added per page##
if params[:q].present?
@books = @search.result.order("created_at DESC").page(params[:page]).per(10)
else
@books = Book.order("created_at DESC").page(params[:page]).per(10)
end
end
def search
index
render :index
end
#...Other Methods..##
#...Other Methods..##
private
def book_params
params.require(:book).permit(:q, :search, :user_id, :title, :description, :author)
end
end
In my routes file, i added the following method, to easily call my search from my views.
#File: config/routes.rb
Rails.application.routes.draw do
resources :books do
collection do
match 'search' => 'books#search', via: [:get, :post], as: :search
end
end
end
In my Index view, now i can directly call for my search method by adding a simple form, a simple search box in this case. Please note that i’m showing only the ‘search’ part of my index view.
#File: app/views/books/index.html.erb
<%= search_form_for @search, url: search_books_path, html: { method: :post } do |f| %>
<div class="input-group">
<%= f.search_field :title_or_author_or_description_cont, placeholder: "Search" %>
<%= f.submit %>
</div>
<% end %>
Now i can search for the books by author, title or by description, you can also add other search parameters, if you want to do so.
Final Thoughts
So i got the result that i wanted and it was quick and easy to do and it works faster if there are not so many concurrent users. But in future i would want to add autocomplete, caching, etc to my search to make my searches even faster and better, I will post an update sometime later on this blog on how to do it better.
There are also other gems that you can use to add search functionality in your app with gems such as searchkick. And also there are better ways to add search like indexing searches with elasticache and adding auto-completion, etc. If you use other gems or other methods to add searches in your rails apps, please let me know.
ok that was a helpful guide, thnks