
Written June 15, 2007. Tagged Ruby, Ruby on Rails.
Still playing with Solr/acts_as_solr.
The site I'm working on uses will_paginate for pagination. It turned out to be pretty easy to get that working with results from acts_as_solr.
The solution is to add a find_all_by_solr method that wraps find_by_solr and returns the records of the returned SearchResults.
Stick solr_pagination.rb in lib in your Rails project.
# By Henrik Nyh <https://henrik.nyh.se> 2007-06-18.
# Free to modify and redistribute with credit.
# Adds a find_all_by_solr method to acts_as_solr models to enable
# will_paginate for acts_as_solr search results.
module ActsAsSolr
module PaginationExtension
def find_all_by_solr(*args)
find_by_solr(*args).records
end
end
end
module ActsAsSolr::ClassMethods
include ActsAsSolr::PaginationExtension
endThen ensure that this code is actually run, by adding
require 'solr_pagination'to config/environment.rb. It wouldn't work at the bottom of that file, so I stuck it just before
Rails::Initializer.run do |config|If you want to verify that things work so far, (re)start the script/console and try something like SomeModel.find_all_by_solr("foo", {:limit => 5, :offset => 2}).
And that's the plumbing done.
You want a controller action like
count = SomeModel.count_by_solr(params[:query])
@results = SomeModel.paginate_all_by_solr(params[:query], :page => params[:page], :total_entries => count)and a view like
<dl>
<% @results.each do |result| %>
<dt><%= result.title %></dt>
<dd><%= result.description %></dd>
<% end %>
</dl>
<%= will_paginate @results %>Note that the :total_entries must be specified explicitly to paginate_all_by_solr. find_all_by_solr isn't a regular finder, so will_paginate can't just do a SQL COUNT.
Today's 0.9 release of acts_as_solr made things easier. The code above has been updated.
Below is the old 0.8.5 version of solr_pagination.rb, which had to translate :limit and :offset (used by regular ActiveRecord finders) into :rows and :start (used by find_by_solr), and that got the records directly rather than in a records attribute.
# By Henrik Nyh <https://henrik.nyh.se> 2007-06-15.
# Free to modify and redistribute with credit.
# Adds a find_all_by_solr method to acts_as_solr models to enable
# will_paginate for acts_as_solr search results.
module ActsAsSolr
module PaginationExtension
def find_all_by_solr(query, options)
map = {:limit => :rows, :offset => :start}
map.each do |from, to|
options[to] = options[from]
options.delete(from)
end
find_by_solr(query, options)
end
end
end
module ActsAsSolr::ClassMethods
include ActsAsSolr::PaginationExtension
end