An open API service indexing awesome lists of open source software.

https://github.com/rocksolt/next_page

Pagination for Rails Controllers
https://github.com/rocksolt/next_page

paginate rails

Last synced: 6 months ago
JSON representation

Pagination for Rails Controllers

Awesome Lists containing this project

README

          

[![Gem Version](https://badge.fury.io/rb/next_page.svg)](https://badge.fury.io/rb/next_page)
[![RSpec](https://github.com/RockSolt/next_page/actions/workflows/rspec.yml/badge.svg)](https://github.com/RockSolt/next_page/actions/workflows/rspec.yml)
[![RuboCop](https://github.com/RockSolt/next_page/workflows/RuboCop/badge.svg)](https://github.com/RockSolt/next_page/actions?query=workflow%3ARuboCop)
[![Maintainability](https://api.codeclimate.com/v1/badges/0efe1a9b66a0bf161536/maintainability)](https://codeclimate.com/github/RockSolt/next_page/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:

```ruby
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:

```ruby
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:

```ruby
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:

```ruby
@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.

```ruby
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.

```ruby
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:

```ruby
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:

```ruby
paginate_with default_limit: 25
```

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

```ruby
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:

```ruby
gem 'next_page'
```

And then execute:
```bash
$ bundle
```

Or install it yourself as:
```bash
$ gem install next_page
```

## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).