acts_as_ferret pagination
Ok, Ferret is great, but how to paginate?
I saw several solutions on the net and liked this one the most.
It appears that it’s quite easy to integrate acts_as_ferret with will_paginate, the officially recommended pagination plugin for Rails.
First, a patch is needed. I placed it to a new file in my special place for patches, vendor/plugins/patches/lib; it could also go in some of existing application files, e.g. bottom of environment.rb:
module ActsAsFerret
module ClassMethods
alias :find_all_by_contents :find_by_contents
end
end
Then, in controller:
@users = User.paginate_by_contents(@search.query, :total_entries => User.total_hits(@search.query), :page => params[:page], :per_page => 10)
Change User to your model class here. You can also use sorting here, see Tutorial below for guidelines.
The trick is that will_paginate is friendly to model class’s methods like find_all_by_xxx; acts_as_ferret’s find_by_contents’s name is a bit wrong for it, so we make an alias, and later this method becomes our model’s method, when we put acts_as_ferret statement in the model class definition.
References:
Filed under: acts_as_ferret, rails, tips, will_paginate | 5 Comments
Search
-
You are currently browsing the Artem Vasiliev's Weblog weblog archives.
I placed the first set of code that you posted into ‘vendor/plugins/patches/lib’ and then entered the following in the console (after restarting the console). Any clues to what’s wrong here?
t = Post.paginate_by_contents(‘test’, :total_entries => 10, :page => 1, :per_page => 2)
NoMethodError: undefined method `find_all_by_contents’ for #
from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1613:in `method_missing_without_paginate’
from /Users/liamks/Documents/programs/rails/liamkaufman/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in `method_missing’
from /Users/liamks/Documents/programs/rails/liamkaufman/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:82:in `send’
from /Users/liamks/Documents/programs/rails/liamkaufman/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:82:in `paginate’
from /Users/liamks/Documents/programs/rails/liamkaufman/vendor/plugins/will_paginate/lib/will_paginate/collection.rb:87:in `create’
from /Users/liamks/Documents/programs/rails/liamkaufman/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:76:in `paginate’
from /Users/liamks/Documents/programs/rails/liamkaufman/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:177:in `method_missing’
from (irb):1
Looks like the patch file is not loaded. You need to put its name into vendor/plugins/patches/init.rb file, like this:
require ‘aaf_pagination’
Note you don’t need to mention lib directory there, it’s searched automatically.
Thanks for your reply!
I tried your suggestion and all the errors went away, however, all my search queries turn up nothing. Every single search combo in the console returns:
I decided to uninstall will_paginate plugin and install the mislav-will_paginate gem and use the built in pagination of ferret with the following method:
http://www.jumbabox.com/2008/05/acts_as_ferret-tutorial/
Unfortunately, that technique also returns nothing when I run a query… Given that the null findings occured in the new technique and the technique you suggested I was wondering if you have any ideas on how to remedy it?
You might want to try to use less magic and monkey patching, and just use the two APIs together.
def self.paginate_by_contents(term, opts)
self.paginate(term, {:finder => “find_by_contents”, :total_entries => self.total_hits(term)}.merge(opts || {}))
end
In Rails 2.3 you have to make sure you load acts_as_ferret, will_paginate, and the patch in the right order. In order for me to get this working, I had to put require ‘acts_as_ferret’ above the initialize loop in environment.rb. If I didn’t, the patch would load before acts_as_ferret and result in an error.