Daniel Doubrovkine bio photo

Daniel Doubrovkine

aka dB., @awscloud, former CTO @artsy, +@vestris, NYC

Email Twitter LinkedIn Github Strava
Creative Commons License

I was a bit surprised to see mongoid drop pagination support in 2.0.2 (here and here). It got some people confused (see mongoid#983). In a project that uses will_paginate, this results in very slow large queries, but no other breakage. It looks like Mongoid did the right thing though – their implementation was messy and other extensions do a much cleaner job.

Here’s what I had to do to switch from will_paginate to kaminari. The latter works well with Mongoid 2.0.2.

Replace will_paginate with kaminari in Gemfile.

gem "kaminari", "0.12.4"

Replace all calls to .paginate :page => params[:page], :per_page => 20 with the kaminari methods.

Model.desc(:created_at).page(params[:page]).per(20)

There may be some loading order issues since kaminari injects methods on load. For delayed jobs I had to do the following in the initializer (see #10).

Delayed::Job.send(:include, Kaminari::MongoidExtension::Document)

If you have a shared pagination block (eg. app/views/shared/pagination/_pagination.html.haml) change it to use kaminari layouts.

#pagination
  = paginate items

There’s a pull request #140 for page_entries_info, it looks like it still has a couple of issues. We’ve added config/initializers/kaminari.rb for now.

If you’re paginating arrays you can inject a few methods into a paged result set on-the-fly to make it play nice.

@paged_result_set.instance_eval <<-EVAL
  def current_page
    #{params[:page] || 1}
  end
  def num_pages
    count
  end
  def limit_value
    20
  end
EVAL