#
Pagy::Backend
This module provides a generic pagination method (pagy
) that works with ActiveRecord
out of the box. For any other
collection (e.g. Sequel
, Mongoid
, ...) you may need to override some sub-method
or
For overriding convenience, the pagy
method calls two sub-methods that you may need to override in order to customize it for any
type of collection (e.g. different ORM types, etc.).
Pagy::Backend
returns pagy
instances
Keep in mind that the whole module is basically providing a single functionality: getting a Pagy instance and the paginated records.
You could re-write the whole module as one single and simpler method specific to your need, eventually gaining a few IPS in the
process. If you seek a bit more performance you are encouraged to
Check also the array, searchkick, elasticsearch_rails and meilisearch extras for specific backend customizations.
#
Synopsis
include Pagy::Backend
# use it in some action
def index
@pagy, @records = pagy(Product.some_scope, some_option: 'some option for this instance')
end
#
Methods
All the methods in this module are prefixed with the "pagy_"
string, to avoid any possible conflict with your own methods when
you include the module in your controller. They are also all private, so they will not be available as actions. The methods
prefixed with the "pagy_get_"
string are sub-methods/getter methods that are intended to be overridden, not used directly.
Please, keep in mind that overriding any method is very easy with Pagy. Indeed you can do it right where you are using it: no need of monkey-patching or perform any tricky gimmickry.
pagy(collection, **vars)
This is the main method of this module. It takes a collection object (e.g. a scope), and an optional hash of variables (passed to
the Pagy.new
method) and returns the Pagy
instance and the page of records. For example:
@pagy, @records = pagy(Product.my_scope, some_option: 'get merged in the pagy object')
The built-in pagy
method is designed to be easy to customize by overriding any sub-methods that it calls internally.
If you need to use multiple different types of collections in the same app or action, you may want to define some alternative and
self contained custom pagy
method. (see
pagy_get_count(collection, vars)
Get the count from the collection, considering also the :count_args
variable. Override it if you need to calculate the count in some special way, or cache it. e.g. overriding pagy_get_count
when using mongoid.
pagy_get_page(vars)
Get the page
from the param ,looking at the :page_param
variable. See also Customize the page_param.
pagy_get_items(collection, pagy)
Sub-method called only by the pagy
method, it returns the records belonging to the current page.
Here is its source (it works with most ORMs like ActiveRecord
, Sequel
, Mongoid
, ...):
def pagy_get_items(collection, pagy)
collection.offset(pagy.offset).limit(pagy.limit)
end
Override it if the extraction of the records from your collection works in a different way. For example, if you need to paginate an array:
def pagy_get_items(array, pagy)
array[pagy.offset, pagy.limit]
end
Array
extra for Arrays
In order to paginate arrays, you may want to use the array extra.
#
Writing your own Pagy methods
Sometimes you may need to paginate different kinds of collections (that require different overriding) in the same controller, so
using one single pagy
method would not be an option.
In that case you can define a number of pagy_*
custom methods specific for each collection.
For example: here is a pagy
method that doesn't call any sub-method, that may be enough for your needs:
def pagy_custom(collection, vars = {})
pagy = Pagy.new(count: collection.count(*vars[:count_args]), page: params[:page], **vars)
[pagy, collection.offset(pagy.offset).limit(pagy.limit)]
end
You can easily write a pagy
method for any possible environment: please read how
to Paginate Any Collection for details.
PRs Welcome
If you write some useful backend customizations, please let us know if you can submit a PR for a specific extra or if you need any help to do it.