Paginator

Paginator contains a collection of pagination operations that can be overridden and tailored to the needs.

First of all, it’s always recommended to create a base paginator class Admin::ApplicationPaginator as below, so that devs can have better control of developing global changes/functions:

# app/paginators/admin/application_paginator.rb
class Admin::ApplicationPaginator < Wallaby::ModelPaginator
  base_class!
end

This base paginator can be generated by Wallaby generator as well:

rails g wallaby:install --include-paginator

See Configuration - application_paginator for how to nominate a different base paginator.

Starting with:

Configuration can be set for:

Accessing the pagination information:

  • paginatable? - telling Wallaby whether the collection contains pagination information (e.g. total count, page size and number).
  • total - returning the total number of collection.
  • page_size - returning page size of the collection.
  • page_number - returning page number of the collection.

Declaration

Read more at Paginator Naming Convention

Let’s see how a paginator can be created so that Wallaby knows its existence.

Similar to the way in Rails, create a custom paginator for model Product inheriting from Admin::ApplicationPaginator (the base paginator mentioned above) as below:

# app/paginators/product_paginator.rb
class ProductPaginator < Admin::ApplicationPaginator
end

If ProductPaginator is taken, it is still possible to use another name (e.g. Admin::ProductPaginator). However, the attribute model_class must be specified. See model_class for examples.

.base_class!

All paginators will be preloaded and processed by Wallaby in order to build up the mapping between paginators and models. If the paginator is considered not to be processed, it can be flagged by using base_class!:

# app/paginators/admin/special_paginator.rb
class Admin::SpecialPaginator < Admin::ApplicationPaginator
  base_class!
end

.model_class

According to Wallaby’s Paginator Naming Convention, if a custom paginator cannot reflect the association to the correct model, for example, as Admin::ProductPaginator to Product, it is required to specify the model class in the paginator as below:

# app/paginators/admin/product_paginator.rb
class Admin::ProductPaginator < Admin::ApplicationPaginator
  self.model_class = Product
end

Pagination

The paginator is initialized with the collection and params, which are accessible as instance variables @collection and @params inside the paginator. It also exposes the following methods (delegated to the underlying pagination provider):

  • paginatable?, first_page?, prev_page?, last_page?, next_page?
  • from, to, total, page_size, page_number
  • first_page_number, last_page_number, prev_page_number, next_page_number, number_of_pages

paginatable?

This is the template method to tell Wallaby whether the collection contains pagination information.

Since most of the models should behave similar, to customize this template, it mostly happen in base paginator as below:

# app/paginators/admin/application_paginator.rb
class Admin::ApplicationPaginator < Wallaby::ModelPaginator
  def paginatable?
    @collection.respond_to? :total_count
  end
end

total

This is the template method to return the total number of collection.

Since most of the models should behave similar, to customize this template, it mostly happen in base paginator as below:

# app/paginators/admin/application_paginator.rb
class Admin::ApplicationPaginator < Wallaby::ModelPaginator
  def total
    @collection.size
  end
end

page_size

This is the template method to return the page size of collection.

Since most of the models should behave similar, to customize this template, it mostly happen in base paginator as below:

# app/paginators/admin/application_paginator.rb
class Admin::ApplicationPaginator < Wallaby::ModelPaginator
  def page_size
    @params[:page_size] || @params[:per]
  end
end

page_number

This is the template method to the page number of collection.

Since most of the models should behave similar, to customize this template, it mostly happen in base paginator as below:

# app/paginators/admin/application_paginator.rb
class Admin::ApplicationPaginator < Wallaby::ModelPaginator
  def page_number
    @params[:page] || 1
  end
end