next_page 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +87 -0
- data/Rakefile +17 -0
- data/lib/next_page/pagination.rb +80 -0
- data/lib/next_page/pagination_attributes.rb +25 -0
- data/lib/next_page/paginator.rb +74 -0
- data/lib/next_page/version.rb +3 -0
- data/lib/next_page.rb +9 -0
- data/lib/tasks/next_page_tasks.rake +5 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 27b21fc2e5c1a3e37922ea3b59773ed5e77de3a280174483a2c21bed5bfb71bb
|
4
|
+
data.tar.gz: 8e7543e8bd5189c1a2971eefe1fd410eaabbf1148eae011ee4d43b9e9a9f3b03
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 306a91bf0c79a6f6a55a1cd43460129884789f475bd2555ddb7c526cf73be99a2e112cef046ef268549f1dd46f9f58b0c9408b121cea9d82ae38ae8bc82b15a4
|
7
|
+
data.tar.gz: 36b53d6be6024623ffe2297b675fbfd67b9da94a29312d44112cad0405a977c7a319bb3300525e480c1494bf28b75138e400d703ce3fe645825b975645720f81
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2020 Todd Kummer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# NextPage
|
2
|
+
Basic pagination for Rails controllers.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
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.
|
6
|
+
|
7
|
+
### Include the Module
|
8
|
+
Add an include statement for the module into any controller that needs pagination:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
include NextPage::Pagination
|
12
|
+
```
|
13
|
+
|
14
|
+
There are two ways to paginate: using a before filter or by calling `paginate_resource` explicitly.
|
15
|
+
|
16
|
+
### Before Filter
|
17
|
+
Here's an example of using the before filter in a controller:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
before_action :apply_next_page_pagination, only: :index
|
21
|
+
```
|
22
|
+
|
23
|
+
This entry point uses the following conventions to apply pagination:
|
24
|
+
- the name of the instance variable is the sames as the component (for example PhotosController -> @photos)
|
25
|
+
- the name of the models is the controller name singularized (for example PhotosController -> Photo)
|
26
|
+
|
27
|
+
Either can be overridden by calling method `paginate_with` in the controller. The two override options are
|
28
|
+
`instance_variable_name` and `model_class`. For example, if the PhotosController used the model Picture and the
|
29
|
+
instance variable name @photographs, the controller declares it as follows:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
paginate_with instance_variable_name: :photographs, model_class: 'Picture'
|
33
|
+
```
|
34
|
+
|
35
|
+
If the before filter is used, it will populate an instance variable. The action should NOT reset the variable, as
|
36
|
+
that removes pagination.
|
37
|
+
|
38
|
+
### Invoking Pagination Directly
|
39
|
+
To paginate a resource pass the resource into method `paginate_resource` then store the return value back in the
|
40
|
+
resource:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
@photos = paginate_resource(@photos)
|
44
|
+
```
|
45
|
+
|
46
|
+
|
47
|
+
### Default Limit
|
48
|
+
The default size limit can be overridden with the `paginate_with` method for either type of paginagion. Pass option
|
49
|
+
`default_limit` to specify an override:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
paginate_with default_limit: 25
|
53
|
+
```
|
54
|
+
|
55
|
+
All the options can be mixed and matches when calling `paginate_with`:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
paginate_with model_class: 'Photo', default_limit: 12
|
59
|
+
paginate_with default_limit: 12, instance_variable_name: 'data'
|
60
|
+
```
|
61
|
+
|
62
|
+
### Link Helpers
|
63
|
+
This gem does not do any rendering. It does provide helper methods for generating links. The resource will include the following additional methods:
|
64
|
+
- current_page
|
65
|
+
- next_page
|
66
|
+
- total_pages
|
67
|
+
- per_page
|
68
|
+
|
69
|
+
## Installation
|
70
|
+
Add this line to your application's Gemfile:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
gem 'next_page'
|
74
|
+
```
|
75
|
+
|
76
|
+
And then execute:
|
77
|
+
```bash
|
78
|
+
$ bundle
|
79
|
+
```
|
80
|
+
|
81
|
+
Or install it yourself as:
|
82
|
+
```bash
|
83
|
+
$ gem install next_page
|
84
|
+
```
|
85
|
+
|
86
|
+
## License
|
87
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'NextPage'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NextPage
|
4
|
+
# = Pagination
|
5
|
+
#
|
6
|
+
# Module Pagination provides pagination for index methods. It assigns a limit and offset
|
7
|
+
# to the resource query and extends the relation with mixin NextPage::PaginationAttributes.
|
8
|
+
#
|
9
|
+
# There are two ways to paginate: using a before filter or by calling `paginate_resource` explicitly.
|
10
|
+
#
|
11
|
+
# == Before Filter
|
12
|
+
# Here's an example of using the before filter in a controller:
|
13
|
+
# before_action :apply_next_page_pagination, only: :index
|
14
|
+
#
|
15
|
+
# This entry point uses the following conventions to apply pagination:
|
16
|
+
# - the name of the instance variable is the same as the component (for example PhotosController -> @photos)
|
17
|
+
# - the name of the model is the controller name singularized (for example PhotosController -> Photo)
|
18
|
+
#
|
19
|
+
# Either can be overridden by calling method `paginate_with` in the controller. The two override options are
|
20
|
+
# `instance_variable_name` and `model_class`. For example, if the PhotosController used the model Picture and the
|
21
|
+
# instance variable name @photographs, the controller declares it as follows:
|
22
|
+
# paginate_with instance_variable_name: :photographs, model_class: 'Picture'
|
23
|
+
#
|
24
|
+
# If the before filter is used, it will populate an instance variable. The action should NOT reset the variable, as
|
25
|
+
# that removes pagination.
|
26
|
+
#
|
27
|
+
# == Invoking Pagination Directly
|
28
|
+
# To paginate a resource pass the resource into method `paginate_resource` then store the return value back in the
|
29
|
+
# resource:
|
30
|
+
#
|
31
|
+
# @photos = paginate_resource(@photos)
|
32
|
+
#
|
33
|
+
# == Default Limit
|
34
|
+
# The default size limit can be overridden with the `paginate_with` method for either type of pagination. Pass option
|
35
|
+
# `default_limit` to specify an override:
|
36
|
+
#
|
37
|
+
# paginate_with default_limit: 25
|
38
|
+
#
|
39
|
+
# All the options can be mixed and matches when calling `paginate_with`:
|
40
|
+
#
|
41
|
+
# paginate_with model_class: 'Photo', default_limit: 12
|
42
|
+
# paginate_with default_limit: 12, instance_variable_name: 'data'
|
43
|
+
module Pagination
|
44
|
+
extend ActiveSupport::Concern
|
45
|
+
|
46
|
+
class_methods do
|
47
|
+
def next_page_paginator #:nodoc:
|
48
|
+
@next_page_paginator ||= NextPage::Paginator.new(controller_name, controller_path)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Configure pagination with any of the following options:
|
52
|
+
# - instance_variable_name: explicitly name the variable if it does not follow the convention
|
53
|
+
# - model_class: explicitly specify the model name if it does not follow the convention
|
54
|
+
# - default_limit: specify an alternate default
|
55
|
+
def paginate_with(instance_variable_name: nil, model_class: nil, default_limit: nil)
|
56
|
+
next_page_paginator.paginate_with(instance_variable_name, model_class, default_limit)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Called with before_action in order to automatically paginate the resource.
|
61
|
+
def apply_next_page_pagination
|
62
|
+
self.class.next_page_paginator.paginate(self, params[:page])
|
63
|
+
end
|
64
|
+
|
65
|
+
# Invokes pagination directly, the result must be stored as the resource itself is not modified.
|
66
|
+
def paginate_resource(resource)
|
67
|
+
self.class.next_page_paginator.paginate_resource(resource, params[:page])
|
68
|
+
end
|
69
|
+
|
70
|
+
def render(*args) #:nodoc:
|
71
|
+
return super unless action_name == 'index' && request.headers[:Accept] == 'application/vnd.api+json'
|
72
|
+
|
73
|
+
options = args.first
|
74
|
+
return super unless options.is_a?(Hash) && options.key?(:json)
|
75
|
+
|
76
|
+
options[:meta] = options.fetch(:meta, {}).merge!(total_pages: options[:json].total_pages)
|
77
|
+
super
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NextPage
|
4
|
+
# = Pagination Attributes
|
5
|
+
#
|
6
|
+
# Module PaginationAttributes adds in methods required for pagination links: current_page, next_page, and total_pages.
|
7
|
+
# It reads the offset and limit on the query to determine the values.
|
8
|
+
module PaginationAttributes
|
9
|
+
def current_page
|
10
|
+
@current_page ||= offset_value + 1
|
11
|
+
end
|
12
|
+
|
13
|
+
def next_page
|
14
|
+
current_page + 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def total_pages
|
18
|
+
@total_pages ||= unscope(:limit).count / per_page
|
19
|
+
end
|
20
|
+
|
21
|
+
def per_page
|
22
|
+
@per_page ||= limit_value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NextPage
|
4
|
+
# = Paginator
|
5
|
+
#
|
6
|
+
# Class Paginator uses the controller information to determine the model and variable name for the
|
7
|
+
# request, then applies a limit and offset to the query based upon the parameters or the defaults. It also extends
|
8
|
+
# the resource with the NextPage::PaginationAttributes mixin.
|
9
|
+
#
|
10
|
+
# Configuration can be specified in the controller by calling `paginate_with`. The following overrides can be
|
11
|
+
# specified if necessary:
|
12
|
+
# - default_limit: limit to use if request does not specify (default value is 10)
|
13
|
+
# - instance_variable_name: default value is the controller name; for example, @photos in PhotosController
|
14
|
+
# - model_class: default derived from controller name (or path if nested); for example, Photo for PhotosController
|
15
|
+
class Paginator
|
16
|
+
DEFAULT_LIMIT = 10
|
17
|
+
|
18
|
+
def initialize(controller_name, controller_path)
|
19
|
+
@controller_name = controller_name
|
20
|
+
@controller_path = controller_path
|
21
|
+
|
22
|
+
@default_limit = DEFAULT_LIMIT
|
23
|
+
end
|
24
|
+
|
25
|
+
def paginate_with(instance_variable_name, model_class, default_limit)
|
26
|
+
@default_limit = default_limit if default_limit.present?
|
27
|
+
@instance_variable_name = instance_variable_name
|
28
|
+
@model_class = model_class.is_a?(String) ? model_class.constantize : model_class
|
29
|
+
end
|
30
|
+
|
31
|
+
def paginate(controller, page_params)
|
32
|
+
name = "@#{instance_variable_name}"
|
33
|
+
data = controller.instance_variable_get(name) || model_class.all
|
34
|
+
|
35
|
+
controller.instance_variable_set(name, paginate_resource(data, page_params))
|
36
|
+
end
|
37
|
+
|
38
|
+
def paginate_resource(data, page_params)
|
39
|
+
data.extend(NextPage::PaginationAttributes)
|
40
|
+
|
41
|
+
limit = page_size(page_params)
|
42
|
+
offset = page_number(page_params) - 1
|
43
|
+
data.limit(limit).offset(offset * limit)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def model_class
|
49
|
+
@model_class ||= @controller_name.classify.safe_constantize ||
|
50
|
+
@controller_path.classify.safe_constantize ||
|
51
|
+
raise('Could not determine model for pagination; please specify using `paginate_with` options.')
|
52
|
+
end
|
53
|
+
|
54
|
+
def instance_variable_name
|
55
|
+
@instance_variable_name ||= @controller_name
|
56
|
+
end
|
57
|
+
|
58
|
+
def page_size(page)
|
59
|
+
if page.present? && page[:size].present?
|
60
|
+
page[:size]&.to_i
|
61
|
+
else
|
62
|
+
@default_limit
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def page_number(page)
|
67
|
+
if page.present? && page[:number].present?
|
68
|
+
page[:number]&.to_i
|
69
|
+
else
|
70
|
+
1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/next_page.rb
ADDED
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: next_page
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Todd Kummer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.2
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 6.0.2.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 6.0.2
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 6.0.2.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: guard
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.16'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.16'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '4.7'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '4.7'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: guard-rubocop
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 1.3.0
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.3.0
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: pg
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.2.3
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.2.3
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec-rails
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '3.9'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '3.9'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rubocop
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.77'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.77'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: simplecov
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0.18'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.18'
|
131
|
+
description: Provide basic pagination, including page size and number as well as helpers
|
132
|
+
for generating links.
|
133
|
+
email:
|
134
|
+
- todd@rockridgesolutions.com
|
135
|
+
executables: []
|
136
|
+
extensions: []
|
137
|
+
extra_rdoc_files: []
|
138
|
+
files:
|
139
|
+
- MIT-LICENSE
|
140
|
+
- README.md
|
141
|
+
- Rakefile
|
142
|
+
- lib/next_page.rb
|
143
|
+
- lib/next_page/pagination.rb
|
144
|
+
- lib/next_page/pagination_attributes.rb
|
145
|
+
- lib/next_page/paginator.rb
|
146
|
+
- lib/next_page/version.rb
|
147
|
+
- lib/tasks/next_page_tasks.rake
|
148
|
+
homepage: https://github.com/RockSolt/next_page
|
149
|
+
licenses:
|
150
|
+
- MIT
|
151
|
+
metadata: {}
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubygems_version: 3.0.8
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: Pagination for Rails Controllers
|
171
|
+
test_files: []
|