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
end
Then 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