Hacking the Ultrasphinx plugin to work with paginating_find

Plugins, Ruby on Rails Add comments

If you’ve been following our blog you may have noticed that we’re using Solr and ActsAsSolr plugin for our searching.

Getting started with acts_as_solr
acts_as_solr for development and production in one Tomcat instance
Optimizing Solr and Rails – Index in the background

Unfortunately being Java, Solr is a bit of a memory hog. We’ve attempted all sorts of optimizations, but we’re going to take a leap and switch to Sphinx. Sphinx is a free open-source SQL full-text search engine.

First step is to get Sphinx itself installed. For that have a look at Rob’s post:
http://www.notch8.com/articles/2007/10/15/sphinx-and-ultrasphinx-and-eye-on-search

Ultrasphinx works pretty much out of the box with will_paginate; however, a lot of our work is currently compatible with paginating_find. So to keep rails memory footprint down by using one plugin we’re sticking with paginating_find. Unfortunately Ultrasphinx doesn’t work out of the box with paginating_find, so time for a little hacking…

Install paginating_find plugin:

piston import http://svn.cardboardrocket.com/paginating_find/paginating_find vendor/plugins/paginating_find

More information on paginating_find

Install ultrasphinx plugin:

piston import http://fauna.rubyforge.org/svn/ultrasphinx/trunk/ vendor/plugins/ultrasphinx

More information on Ultrasphinx

Now for hacking Ultrasphinx plugin to work with Paginating Find plugin. Piston is great for managing plugins; however, it can easily get confused if you’ve hacked a plugin directly. The solution: use a method called “Evil Twin” as mentioned on the Err the Blog: Evil Twin Plugin

Create a directory for the hack:

mkdir vendor/plugins/ultrasphinx_hacks
touch vendor/plugins/ultrasphinx_hacks/init.rb

Now edit the vendor/plugins/ultrasphinx_hacks/init.rb file with the hacks for paginating_find:

# Hack to allow Ultrasphinx to work with pagination_find
Ultrasphinx::Search.module_eval do
def first_page
1
end

def last_page
self.page_count
end

def previous_page?
previous_page ? true : false
end

def next_page?
next_page ? true : false
end
end

Now for adding a method to your controller for the search:

app/controllers/posts_controller.rb

def search
@query = h(params[:query])
begin
@posts = Ultrasphinx::Search.new(:query => @query,
:class_names => ‘Post’,
:page => params[:page] || 1, :per_page => 20)
@ posts.run
rescue RuntimeError
flash[:warning] = ‘Search is currently disabled. Please try again in a few hours.’
rescue NoMethodError
flash[:notice] = ‘No records found for this search’
end
render :action => ‘list’
end

app/views/posts/list.html.erb

    < % @posts.each do |cog| %>

  • < %= posts.name %>
  • < % end %>

< %= paginating_links(@posts) %>

Paginating End Result

Bonus : will_paginate styled links

Unfortunately paginating_find doesn’t automatically have the “style” that will_paginate automatically comes with. So to fix that just add a little css for the style and a partial for the pervious and next buttons.

.pagination{
padding: 2px;
}
.pagination a, .pagination a:visited{
padding: 0 5px;
border: 1px solid #9aafe5;
text-decoration: none;
color: #2e6ab1;
}

.pagination a:hover, .pagination a:active{
border: 1px solid #2b66a5;
color: #000;
}

.pagination .currentpage{
font-weight: bold;
padding: 0 5px;
border: 1px solid navy;
background-color: #2e6ab1;
color: #FFF;
}

.pagination .disablepage{
padding: 0 5px;
border: 1px solid #929292;
color: #929292;
display: inline;
}

And now for the partial:

app/views/shared/_paginate.html.erb

< % if (collection.is_a?(PagingEnumerator) || collection.is_a?(Ultrasphinx::Search)) && (collection.page_count != collection.first_page) -%>

< % end -%>

So in your code replace the code paginating_links call with a render partial:

# OLD VERSION
< %= paginating_links(@posts) %>
# NEW VERSION
< %= render :partial => ‘shared/paginate’, :locals => {:collection => @posts} %>

Styled Paginating End Result

Resources:
ErrTheBlog: Evil Twin Plugin
Will Paginate Plugin
Paginating Find Plugin
Ultrasphinx
Sphinx

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in