Project

next_page

0.0
There's a lot of open issues
Provide basic pagination, including page size and number as well as helpers for generating links.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.5.0
~> 4.7.3
~> 1.5.4
~> 5.1.2
~> 1.60.1
~> 2.18.0
~> 0.18

Runtime

>= 6.1.7
 Project Readme

Gem Version RSpec RuboCop Maintainability

NextPage

Basic pagination for Rails controllers.

Usage

Module Pagination provides pagination for index methods. It assigns a limit and offset to the resource query and extends the relation with mixin NextPage::PaginationAttributes to provide helper methods for generating links.

Include the Module

Add an include statement for the module into any controller that needs pagination:

include NextPage::Pagination

There are two ways to paginate: using a before filter or by calling paginate_resource explicitly.

Before Filter

Here's an example of using the before filter in a controller:

before_action :apply_next_page_pagination, only: :index

This entry point uses the following conventions to apply pagination:

  • the name of the instance variable is the sames as the component (for example PhotosController -> @photos)
  • the name of the models is the controller name singularized (for example PhotosController -> Photo)

Either can be overridden by calling method paginate_with in the controller. The two override options are instance_variable_name and model_class. For example, if the PhotosController used the model Picture and the instance variable name @photographs, the controller declares it as follows:

paginate_with instance_variable_name: :photographs, model_class: 'Picture'

If the before filter is used, it will populate an instance variable. The action should NOT reset the variable, as that removes pagination.

Invoking Pagination Directly

To paginate a resource pass the resource into method paginate_resource then store the return value back in the resource:

@photos = paginate_resource(@photos)

Sorting

Requests can specify sort order using the parameter sort with an attribute name or scope. Sorts can be prefixed with + or - to indicate ascending or descending. Multiple sorts can be specified either as a comma separated list or via bracket notation.

/photos?sort=-created_at
/photos?sort=location,-created_by
/photos?sort[]=location&photos[]=-created_by

The default sort order is primary key descending. It can be overridden by using the default_sort option of paginate_with. Use a string formatted just as url parameter would be formatted.

paginate_with default_sort: '-created_at'

Nested Sorts

Nested attributes and scopes can be indicated by providing the association names separated by periods.

/photos?sort=user.name
/photos?sort=-user.address.state

Directional Scope Sorts

In order to use directions (+ or -) with a scope, the scope must be defined as a class method and take a single parameter. The scope will receive either 'asc' or 'desc'. Here is an example of a valid directional scope.

def self.status(direction)
  order("CASE status WHEN 'new' THEN 1 WHEN 'in progress' THEN 2 ELSE 3 END #{direction}")
end

Scope Prefix / Suffix

In order to keep the peace between frontend and backend developers, scope names can include a prefix or suffix that the front end can ignore. For example, given a scope that sorts on a derived attribute (such as status in the Direction Scope Sorts example), the backend developer might prefer to name the scope status_sort or sort_by_status, as a class method that shares the same name as an attribute might be unclear. However, the frontend developer does not want a query parameter that says sort=sort_by_status; it is an exception because it doesn't match the name of the attribute (and it's not pretty).

The configuration allows a prefix and or suffix to be specified. If either is specified, then in addition to looking for a scope that matches the parameter name, it will also look for a scope that matches the prefixed and/or suffixed name. Prefixes are defined by configuration option sort_scope_prefix and suffixes are defined by sort_scope_suffix.

For example, if the backend developer prefers sort_by_status then the following configuration can be used:

NextPage.configure do |config|
  config.sort_scope_prefix = 'sort_by_'
end

This allows the query parameter to be the following:

sort=status

Default Limit

The default size limit can be overridden with the paginate_with method for either type of paginagion. Pass option default_limit to specify an override:

paginate_with default_limit: 25

All the options can be mixed and matches when calling paginate_with:

paginate_with model_class: 'Photo', default_limit: 12
paginate_with default_limit: 12, instance_variable_name: 'data'

Link Helpers

This gem does not do any rendering. It does provide helper methods for generating links. The resource will include the following additional methods (when the request header Accept is 'application/vnd.api+json'):

  • current_page
  • next_page
  • total_pages
  • per_page

Count Query

In some cases (such as grouping), calling count on the query does not provide an accurate representation. If that is the case, then there are two ways to override the default behavior:

  • provide a count_query that can resolve the attributes
  • specify the following attributes manually: current_page, total_count, and per_page

Installation

Add this line to your application's Gemfile:

gem 'next_page'

And then execute:

$ bundle

Or install it yourself as:

$ gem install next_page

License

The gem is available as open source under the terms of the MIT License.