# Pagy::Backend

In 
Core

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 write your own Pagy methods.

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.).

Check also the array, searchkick, elasticsearch_rails and meilisearch extras for specific backend customizations.

# Synopsis

Controller
include Pagy::Backend

# optional overriding of some sub-method
def pagy_get_vars(collection, vars)
  #...
end

# 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.

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 of the two sub-methods that it calls internally. You can independently change the default variables (pagy_get_vars) and/or the default page of items from the collection pagy_get_items).

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 Writing your own Pagy methods)

Sub-method called only by the pagy method, it returns the hash of variables used to initialize the Pagy object.

Override it if you need to add or change some variable. For example you may want to add the :item_name in order to customize the output (see How to customize the item name).

See also the How To page for some usage examples.

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.

Get the page from the param ,looking at the :page_param variable. See also Customize the page_param.

Sub-method called only by the pagy method, it returns the page items (i.e. 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.items)
end

Override it if the extraction of the items 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.items]
end

# 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:

Controller

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.items)]
end

You can easily write a pagy method for any possible environment: please read how to Paginate Any Collection for details.