Simple Full Text Search in Rails

WebDev Rails

No gems, no dependencies, no complexity. Here’s a basic full text search to use on simpler, smaller rails apps.

Don’t get me wrong, I love ElasticSearch, or Ransack for larger more complex projects. But sometimes you just need something simple. This website for example.

At the time of writing this I’ve implemented search using plain old Ruby. This example does “full text” search, also searches the full text across multiple attributes, lastly, it also supports searching within ActionText as well.

Here's the basics for Searching the Post model within this blog.

I have a before_action for the controller to a set_scope method: 

before_action :set_scope, only: :index

Here's that set_scope method: 


  def set_scope
    @posts = Post.all
    if params[:search]
      basics = search_basics
      body = search_body
      tags = search_tags
      post_ids = basics | body | tags
      @posts = @posts.find(post_ids)
    end
  end

  def search_basics
    @posts.where(
      "title ilike ? OR description ilike ?",
      "%#{params[:search]}%","%#{params[:search]}%"
    ).pluck(:id)
  end

  def search_body
    @posts.joins(:action_text_rich_text)
      .where(
        "action_text_rich_texts.body ilike ?",
        "%#{params[:search]}%"
      ).pluck(:id)
  end

  def search_tags
    tags = params[:search].split(" ")
    Post.tagged_with(tags, :any => true).pluck(:id)
  end

Here's how I render my basic search bar at the top of my posts index to wire it up in the view: 

<form id="search" action="<%= posts_path %>">
  <div class="input-group">
    <%= text_field_tag :search, params[:search], id: 'content_search_term',class: 'form-control', placeholder:'Search...' %>
    <div class="input-group-append">
      <button class="btn btn-primary" type="submit" id="button-addon2">Search</button>
    </div>
  </div>
  <% unless params[:search].blank? %>
    <small><%= pluralize(@posts.count, "post", "posts") %> found for search "<%= params[:search] %>" <a href="<%= posts_path %>" class="text-muted pl-2 text-decoration-none"><i class="fas fa-times"></i> Clear Search</a></small>
  <% end %>
</form>

Bottom Line

This is not the cleanest or most performant way to do search in rails, but sometimes simpler is better. If you only have a couple hundred records to search and don't need "sloppy" search, this hack will probably suffice. Otherwise, there's plenty of resources out there on Elastic search and search-kick. 

 

Similar Posts

Debugging AWS S3 for Rails Active Storage

It could be your CORS configuration for AWS S3 for Rails ActiveStorage

Tech WebDev Rails

Refactoring Rails: Form Objects

Form objects let you work with many objects at once in rails. It's a pattern that's a lot more powerful and clean than accepts_nested_attributes.

WebDev Rails

Refactoring Rails: Callbacks

I've abused callbacks enough to know they have limits. This post is some summarized notes on the recommendations for using callbacks effectively.

WebDev Rails