Thinking Sphinx with Paginating Find

The Thinking Sphinx plugin comes wired to work directly with will_paginate. However, I use the paginating_find instead.

I placed this block of code in a new file called thinking_sphinx_patch.rb and placed it in my config/initializers folder.

module ThinkingSphinx
  class Search
    class << self
      def search_with_paginating_find(*args)
        query = args.clone  # an array
        options = query.extract_options!

        retry_search_on_stale_index(query, options) do
          results, client = search_results(*(query + [options]))

          ::ActiveRecord::Base.logger.error(
            "Sphinx Error: #{results[:error]}"
          ) if results[:error]

          klass   = options[:class]
          page    = options[:page] ? options[:page].to_i : 1
          total = results[:total]

          results = ThinkingSphinx::Collection.create_from_results(results, page, client.limit, options)

          if options[:page]
            PagingEnumerator.new(client.limit, total, false, page, 1) do |pg|
              results
            end
          else
            results
          end
        end
      end
      alias_method_chain :search, :paginating_find
 
    end
  end
end

The Thinking Sphinx version works by gathering all the results of a query from Sphinx and then passing back a slice that matches your pagination and limit options. To make it work with paginating_find, we needed simply to wrap the results array in a PagingEnumerator while the total number of results is still available.

February 26, 2009 in Ruby on Rails