Live fulltext search in Ruby on Rails
Some time ago I promised to create a small tutorial about live fulltext search. A fulltext search, that gives you results as you type.
Ingredients:
- Ruby on rails
- ferret gem (gem install ferret)
- acts_as_ferret gem (gem install acts_as_ferret)
- auto_complete plugin (from the application root: ruby script/plugin install auto_complete)
What we will do
- Create an empty application – simple book database
- Add fulltext search capabilities
- Create the live search
-
- Create search pane partial – the one that will display the search box
- Create the search results partial – that will render the hints (search results)
- Modify controller to respond to the search pane
Create a book database application
We will create a small application for book management. It will store, list, update books and it will also provide the live search.
So, lets create the skeleton of the aplication:
# Create the rails application rails books # create database books echo "create database books" | mysql -u root -p cd books
Configure database login and password in app/config/database.yml.
development: adapter: mysql database: books username: root password: password host: localhost port: 3306
Create skeleton of the application. From root of the application run:
ruby script/generate scaffold Book title:string abstract:text
Create the books table
rake db:migrate
Start up the development server
ruby script/server
Now, browse to http://127.0.0.1:3000/books and type in some data.
Add fulltext search capabilities
Change the app/models/book.rb to support fulltext search
require "acts_as_ferret" class Book < ActiveRecord::Base acts_as_ferret end
You can check in the console, that the fulltext is enabled. Just start the console via
ruby script/console and put there
Book.find_by_contents("book").
It should return a result set, similar to this:
=> #<ActsAsFerret::SearchResults:0x2540f54 @results=[#<Book id: 2, title: "Book secondo", abstract: "Book about book", created_at: "2008-07-07 23:16:38", updated_at: "2008-07-07 23:16:38">, #<Book id: 1, title: "First book", abstract: "This is a first book", created_at: "2008-07-07 23:16:23", updated_at: "2008-07-07 23:16:23">], @total_hits=2>Create the live search
Finally, create the live search.
Create search pane partial
The search_pane will be used to display search box.
Create a partial _search_pane.html.erb in app/views/books and put there simple tag. The tag create Ajax Autocompleter that calls auto_complete_for_search_query method of the default controller (in our case it will be books)
<%= text_field_with_auto_complete :search, :query %>
Add javascript include and partial rendering to the books template app/views/layouts/books.html.erb.
Do not forget! The javascript include must be in the head of the template.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Books: <%= controller.action_name %></title>
<!-- HERE -->
<%= stylesheet_link_tag 'scaffold' %>
<%= javascript_include_tag :defaults %>
</head>
<body>
<!-- AND HERE -->
<%= render :partial=>"books/search_pane" %>
<p style="color: green"><%= flash[:notice] %></p>
<%= yield %>
</body>
</html>Create the search results partial
The search_results will format the results of the full text search and will “offer” the resulting records. Create a partial app/views/books/_search_results.html.erb and add there the formatting code:
<ul> <% for book in @books %> <li><%= link_to h(book.title), :controller=>"books", :action=>"show", :id=>book %></li> <% end %> </ul>
Modify controller
Add the following line at the beginning of the books_controller.
protect_from_forgery :only => [:create, :update, :destroy]
Create a method in books_controller that will search for the books
def auto_complete_for_search_query @books = Book.find_by_contents(params["search"]["query"]+"*", {:limit => 5}) render :partial => "search_results" end
We do not want to generate the whole page layout, so it is necessary to specify it in the books controller:
layout 'books', :except => [:auto_complete_for_search_query]
And now, navigate to http://127.0.0.1:3000/books and start searching. As soon as you start typing into the search box, it shows results. Click on one of the proposed links to see what happens. Source code is here.
|
| Published on July 10th, 2008 | | Posted by Roman Mackovcak |

July 11th, 2008 at 13:34
[…] Live full text search on ruby on rails Added on 07/11/2008 at 09:30AM […]
August 6th, 2008 at 5:45
Thanks for the example,
I am rendering the search bar partial in a layout, when trying to use the search from outside the context of the controller I get an error about authenticity token (I am guessing this is what you would usually want, but not in this scenario.) Any idea on how to deal with that?
I have protect_from_forgery :only => [:create, :update, :destroy] in my controller.
August 6th, 2008 at 9:46
Andrew,
I am not sure what do you mean. Could you post some code?
August 17th, 2008 at 1:27
Hi
I’ve been playing with this today, and it’s really quite sweet. Many thanks for sharing it with the community. I’m trying to modify it to be aware of more than one model, and while I’ve got it querying across my models, I’m a bit stuck as to how to modify the search_results partial to correctly link to the appropriate model in the results. So, for example, linking to: author, publisher views, as well as book views. Would you have any hints on how to tackle such a thing?
thanks in advance
jp
April 10th, 2009 at 13:16
[…] recorded first by Spyro2008 on 2009-02-23→ Live fulltext search in Ruby on Rails […]
May 1st, 2009 at 8:47
[…] /bin/recykl » Blog Archive » Live fulltext search in Ruby on RailsMinion’s interpretation of “Cream of Angry Soup”A One-Day Diary | ZooniversityLindas Freebie Page » Blog Archive » Free eBooks: Marketing Tips – Volumes 1-3 Day 1255: Darned Rodents : Maitri’s VatulBlogBreedingFerrets.net » Blog Archive » Breeding Ferrets Has MovedCreating A Healthy Ferret Diet | Caring For Your Pets Info Remembering A Friend – Bogey Web Design Where Can I Find Ferrets For Sale in California? | Proper Care For FerretsLife of a Space Ferret » Blog Archive » Whoo! Semester’s Done! […]
May 18th, 2009 at 18:05
[…] Smackdown Round IV – phpBB3 versus phpBB-Dave Saved by TrippinTarheelia on Sun 03-5-2009 Live fulltext search in Ruby on Rails Saved by vitortubino on Sat 02-5-2009 New interface to CINAHL : CINAHL Plus with FullText Saved […]
February 27th, 2010 at 14:26
Thanks, I’d been working on something similar but was struggling with the Javascript. Your example was just the ticket!