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:
- .base_class! - flagging as base class.
- .model_class - specifying the model class.
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_numberfirst_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