Prototyping a site in Ruby on Rails and need to add a simple search feature in less than 5 minutes?
Note: This should be for smaller projects because I’ll be using regular SQL queries for searching. If you’re looking for something more advanced, try thinking_sphinx(sphinx engine) or sunspot_solr(java lucene solr engine).
I’ll be using Searchlogic and will_paginate in this demo.
#install searchlogic
sudo gem install searchlogic
#install will_paginate
gem sources -a http://gemcutter.org
sudo gem install will_paginate
Then add the gem to the environment file.
#config/environment.rb
config.gem "binarylogic-searchlogic", :lib => "searchlogic"
config.gem 'will_paginate', :version => '~> 2.3.11'
If you prefer to use github or the plugin version, check out their docs. I also suggest reading their docs to learn more about all the neat functions Searchlogic can do. It’s a very powerful and useful plugin.
We’ll be adding the search to Posts, so let’s start by adding the search route to our posts.
#config/routes.rb
map.resources :posts, :collection => { :search => [ :post, :get ] }
This will give you the path /posts/search GET and POST.
Next add the search method to the PostsController.
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.paginate(:all, :order => 'created_at desc', :per_page => 25, :page => params[:page])
end
def search
if request.post?
#pass the post into a get with the 'q' param
redirect_to search_posts_path(:q => params[:search][:query])
elsif request.get?
unless params[:q].blank?
#Searchlogics title_like_all to search within titles in the Post model for any of the words in the query.
#words in the string are split into an array by spaces
search = Post.title_like_all(params[:q].to_s.split).descend_by_created_at
#paginate the results
@posts = search.paginate(:per_page => 25, :page => params[:page])
#pass the query object to the view to let the user know what they searched for
@query = params[:q]
end
#render the Post index.html.erb
render 'index'
end
end
end
The last part is the search form in your view.
<p>
<% form_for :search, :url => { :controller => 'posts', :action => 'search' } do |f| %>
<%= f.text_field :query, :value => @query%>
<%= f.submit "Search", :disable_with => "Searching..." %>
<% end %>
</p>