jbuilder_pagination_plus 1.0.0 → 1.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 +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/README.md +55 -5
- data/jbuilder_pagination_plus.gemspec +2 -2
- data/lib/jbuilder/pagination.rb +23 -5
- data/lib/jbuilder/pagination/pages.rb +101 -25
- data/lib/jbuilder/pagination/version.rb +2 -4
- metadata +28 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a546f0bae157155cea8dafe471cd6e7a44dff00cb9a5823f42b53ef2726974d
|
4
|
+
data.tar.gz: dab71bf293fd753e220181d22ab8b9794b45722f532609f55196b442923c1bd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb029327b276555c9e1cb4b05fb7600203dcaa25e8a9e7ebf5b62e2cee523f93d5b967cb6e4c3867b4ff9a4de37d8ff5310f4955109a8ab7e500410329cee815
|
7
|
+
data.tar.gz: 3eb3fe3370f2980db1930c2b27c01d006611ef4b81e6c0496c66840c512f8431f820246cae2135c68ac66dd7592552630b075efdef1c5533d84a4f46422fa108
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.7.1
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
# Jbuilder Pagination Plus [](https://travis-ci.org/IlluminusLimited/jbuilder_pagination_plus) [](https://badge.fury.io/rb/jbuilder_pagination_plus)
|
2
2
|
|
3
|
-
[Jbuilder](https://github.com/rails/jbuilder) extension that makes easier to use pagination according
|
3
|
+
[Jbuilder](https://github.com/rails/jbuilder) extension that makes easier to use pagination according
|
4
|
+
to the [JSON API](http://jsonapi.org/format/#fetching-pagination) conventions.
|
4
5
|
|
5
6
|
Forked from: [https://github.com/bacarini/jbuilder_pagination](https://github.com/bacarini/jbuilder_pagination)
|
6
7
|
|
7
8
|
## Requirement
|
8
9
|
|
9
|
-
`JbuilderPaginationPlus` relies on a paginated collection with the methods `current_page`, `total_pages`,
|
10
|
+
`JbuilderPaginationPlus` relies on a paginated collection with the methods `current_page`, `total_pages`,
|
11
|
+
and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari)
|
12
|
+
or [WillPaginate](https://github.com/mislav/will_paginate).
|
10
13
|
|
11
14
|
## Installation
|
12
15
|
|
@@ -79,13 +82,60 @@ end
|
|
79
82
|
# }
|
80
83
|
# }
|
81
84
|
```
|
82
|
-
The options `url` and `query_parameters` are
|
85
|
+
The options `url` and `query_parameters` are optional.
|
83
86
|
|
84
87
|
In case there is no pagination at all, `links` will be omitted.
|
85
88
|
|
89
|
+
If you want to keep the original query parameters passed in you could do something this:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
json.links do
|
93
|
+
json.pages! @posts, url: request.original_url, query_parameters: { images: params[:images] }
|
94
|
+
end
|
95
|
+
|
96
|
+
json.data do
|
97
|
+
# Whatever your data is
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
jbuilder_pagination_plus will deep merge query parameters with the original request parameters.
|
102
|
+
|
103
|
+
|
104
|
+
If that's not what you need then you can get the url using rails helpers:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
json.links do
|
108
|
+
json.pages! @posts, url: posts_url
|
109
|
+
end
|
110
|
+
|
111
|
+
json.data do
|
112
|
+
# Whatever your data is
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
If you need pagination but don't want the performance penalty of counting all of the records, you can use
|
117
|
+
to generate links without generating a `last` url. This should be compatible with `Kaminari`'s
|
118
|
+
`without_count` scope which can be used to paginate without issuing a `COUNT(*)` query.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
json.links do
|
122
|
+
json.pages_no_count! @posts, url: posts_url
|
123
|
+
end
|
124
|
+
|
125
|
+
json.data do
|
126
|
+
# Whatever your data is
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
The `pages!` method will automatically switch to `no_count` mode if it detects that the collection
|
131
|
+
doesn't respond properly to a `total_pages` method call.
|
132
|
+
|
86
133
|
## Development
|
87
134
|
|
88
|
-
After checking out the repo, run `bin/setup` to install dependencies.
|
135
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
136
|
+
Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
137
|
+
|
138
|
+
To run tests, run `rake spec`
|
89
139
|
|
90
140
|
## Contributing
|
91
141
|
|
@@ -5,13 +5,13 @@ require 'jbuilder/pagination/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "jbuilder_pagination_plus"
|
8
|
-
spec.version =
|
8
|
+
spec.version = Pagination::VERSION
|
9
9
|
spec.authors = ["Bruno Bacarini", "Andrew Newell"]
|
10
10
|
spec.email = ["bacarini.bruno@gmail.com", "scytherswings@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = "Jbuilder extension to allows pagination according to JSON API format"
|
13
13
|
spec.description = "Jbuilder extension to allows pagination according to JSON API format. See http://jsonapi.org for details on the format. Also provides methods for simpler pagination in controllers"
|
14
|
-
spec.homepage = "https://github.com/
|
14
|
+
spec.homepage = "https://github.com/IlluminusLimited/jbuilder_pagination_plus"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
data/lib/jbuilder/pagination.rb
CHANGED
@@ -8,6 +8,20 @@ module Pagination
|
|
8
8
|
DEFAULT_PAGINATION = [[:page, ->(params) { params.dig(:page, :number) }],
|
9
9
|
[:per, ->(params) { params.dig(:page, :size) }]].freeze
|
10
10
|
|
11
|
+
NO_COUNT_PAGINATION = [[:page, ->(params) { params.dig(:page, :number) }],
|
12
|
+
[:per, ->(params) { params.dig(:page, :size) }],
|
13
|
+
[:without_count]].freeze
|
14
|
+
|
15
|
+
# @param pageable_resource [Object] resource to be paged
|
16
|
+
# @param methods [Array<Symbol, Lambda>] array of methods to call on the pageable_resource
|
17
|
+
# @param params [Object] params object from the controller
|
18
|
+
def paginate_no_count(pageable_resource, methods = NO_COUNT_PAGINATION.dup, params = self.params)
|
19
|
+
paginate(pageable_resource, methods, params)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param pageable_resource [Object] resource to be paged
|
23
|
+
# @param methods [Array<Symbol, Lambda>] array of methods to call on the pageable_resource
|
24
|
+
# @param params [Object] params object from the controller
|
11
25
|
def paginate(pageable_resource, methods = DEFAULT_PAGINATION.dup, params = self.params)
|
12
26
|
return pageable_resource if methods.blank?
|
13
27
|
key_value_array = methods.pop
|
@@ -16,11 +30,15 @@ module Pagination
|
|
16
30
|
|
17
31
|
private
|
18
32
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
33
|
+
def build_pagination(key_value_array, pageable_resource, params)
|
34
|
+
unless pageable_resource.respond_to?(key_value_array[0])
|
35
|
+
raise Errors::UnpageableResourceError, "Resource does not respond to '#{key_value_array[0]}' method!"
|
36
|
+
end
|
23
37
|
|
24
|
-
|
38
|
+
if key_value_array[1].nil?
|
39
|
+
return pageable_resource.public_send(key_value_array[0])
|
25
40
|
end
|
41
|
+
|
42
|
+
pageable_resource.public_send(key_value_array[0], key_value_array[1].call(params))
|
43
|
+
end
|
26
44
|
end
|
@@ -1,50 +1,126 @@
|
|
1
1
|
class Jbuilder
|
2
2
|
ONE_PAGE = 1
|
3
3
|
|
4
|
-
|
4
|
+
# Used to generate the pagination links for a collection
|
5
|
+
# @param collection [Object] the paginated collection
|
6
|
+
# @param opts [Hash] options to pass in
|
7
|
+
# @option opts [String] :url The url to use
|
8
|
+
# @option opts [Hash] :query_parameters Query parameters to automatically add to any generated urls
|
9
|
+
# @option opts [Boolean] :no_count This can be passed to force pagination without counting the total which is
|
10
|
+
# an alternative to calling #pages_no_count!
|
11
|
+
def pages!(collection, opts = {})
|
5
12
|
return unless collection && is_paginated?(collection)
|
6
13
|
|
7
|
-
|
14
|
+
options_query_parameters, original_params, original_url = handle_url(opts)
|
15
|
+
|
16
|
+
if opts.fetch(:no_count, false)
|
17
|
+
pages_without_count(collection, options_query_parameters, original_params, original_url)
|
18
|
+
elsif is_countable?(collection)
|
19
|
+
pages_with_count(collection, options_query_parameters, original_params, original_url)
|
20
|
+
else
|
21
|
+
pages_without_count(collection, options_query_parameters, original_params, original_url)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Used to generate the pagination links for a collection without requiring the total_count
|
26
|
+
# @param collection [Object] the paginated collection
|
27
|
+
# @param opts [Hash] options to pass in
|
28
|
+
# @option opts [String] :url for the url to use
|
29
|
+
# @option opts [Hash] :query_parameters to automatically add to any generated urls
|
30
|
+
def pages_no_count!(collection, opts = {})
|
31
|
+
return unless collection && is_paginated?(collection)
|
32
|
+
|
33
|
+
options_query_parameters, original_params, original_url = handle_url(opts)
|
34
|
+
|
35
|
+
pages_without_count(collection, options_query_parameters, original_params, original_url)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def handle_url(opts)
|
41
|
+
options_url = opts.fetch(:url, nil)
|
8
42
|
original_url = nil
|
9
43
|
original_params = {}
|
10
44
|
if options_url
|
11
45
|
original_url, original_params = options_url.split("?")
|
12
46
|
original_params = ::Rack::Utils.parse_nested_query(original_params).deep_symbolize_keys
|
13
47
|
end
|
14
|
-
options_query_parameters =
|
48
|
+
options_query_parameters = opts.fetch(:query_parameters, {})
|
49
|
+
[options_query_parameters, original_params, original_url]
|
50
|
+
end
|
15
51
|
|
52
|
+
def pages_with_count(collection, options_query_parameters, original_params, original_url)
|
16
53
|
pages_from(collection).map do |key, value|
|
17
|
-
|
18
|
-
_set_value key, "#{original_url}?#{params}"
|
54
|
+
build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
|
19
55
|
end
|
20
56
|
end
|
21
57
|
|
22
|
-
private
|
23
58
|
|
24
|
-
def pages_from(collection)
|
25
|
-
{}.tap do |pages|
|
26
|
-
pages[:self] = collection.current_page
|
27
|
-
return pages if collection.total_pages <= ONE_PAGE
|
28
59
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
60
|
+
def pages_without_count(collection, options_query_parameters, original_params, original_url)
|
61
|
+
pages_without_count_from(collection).map do |key, value|
|
62
|
+
build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
|
67
|
+
params = query_parameters(options_query_parameters, original_params)
|
68
|
+
.deep_merge(page: { number: value, size: collection.size })
|
69
|
+
.to_query
|
70
|
+
_set_value key, "#{original_url}?#{params}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def pages_from(collection)
|
74
|
+
{}.tap do |pages|
|
75
|
+
pages[:self] = collection.current_page
|
76
|
+
return pages if collection.total_pages <= ONE_PAGE
|
33
77
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
78
|
+
unless collection.current_page == ONE_PAGE
|
79
|
+
pages[:first] = ONE_PAGE
|
80
|
+
pages[:prev] = collection.current_page - ONE_PAGE
|
38
81
|
end
|
39
|
-
end
|
40
82
|
|
41
|
-
|
42
|
-
|
83
|
+
unless collection.current_page == collection.total_pages
|
84
|
+
pages[:next] = collection.current_page + ONE_PAGE
|
85
|
+
pages[:last] = collection.total_pages
|
86
|
+
end
|
43
87
|
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def pages_without_count_from(collection)
|
91
|
+
{}.tap do |pages|
|
92
|
+
pages[:self] = collection.current_page
|
93
|
+
|
94
|
+
unless collection.current_page == ONE_PAGE
|
95
|
+
pages[:first] = ONE_PAGE
|
96
|
+
pages[:prev] = collection.current_page - ONE_PAGE
|
97
|
+
end
|
44
98
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
99
|
+
if collection.respond_to?(:last_page?) && collection.last_page?
|
100
|
+
# Do nothing
|
101
|
+
return pages
|
102
|
+
else
|
103
|
+
pages[:next] = collection.current_page + ONE_PAGE
|
104
|
+
end
|
49
105
|
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def query_parameters(query_parameters, original_parameters)
|
109
|
+
@query_parameters ||= original_parameters.deep_merge(query_parameters || {}).compact
|
110
|
+
end
|
111
|
+
|
112
|
+
def is_paginated?(collection)
|
113
|
+
collection.respond_to?(:current_page) &&
|
114
|
+
collection.respond_to?(:total_pages) &&
|
115
|
+
collection.respond_to?(:size)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Kaminari raises an exception if you call #total_count on a #without_count-ed collection
|
119
|
+
# Rescue can't be good for performance which is why you should use pages_no_count! if you know you will be
|
120
|
+
# dealing with non-counted collections
|
121
|
+
def is_countable?(collection)
|
122
|
+
collection.total_pages
|
123
|
+
rescue ::StandardError
|
124
|
+
false
|
125
|
+
end
|
50
126
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jbuilder_pagination_plus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno Bacarini
|
@@ -9,88 +9,88 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-09-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - ">="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 2.0.0
|
21
18
|
- - "~>"
|
22
19
|
- !ruby/object:Gem::Version
|
23
20
|
version: '2.0'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.0
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- - ">="
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 2.0.0
|
31
28
|
- - "~>"
|
32
29
|
- !ruby/object:Gem::Version
|
33
30
|
version: '2.0'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: jbuilder
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 2.8.0
|
41
38
|
- - "~>"
|
42
39
|
- !ruby/object:Gem::Version
|
43
40
|
version: '2.8'
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.8.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
46
|
version_requirements: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
|
-
- - ">="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 2.8.0
|
51
48
|
- - "~>"
|
52
49
|
- !ruby/object:Gem::Version
|
53
50
|
version: '2.8'
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.8.0
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: rspec
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 3.8.0
|
61
58
|
- - "~>"
|
62
59
|
- !ruby/object:Gem::Version
|
63
60
|
version: '3.8'
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 3.8.0
|
64
64
|
type: :development
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- - ">="
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: 3.8.0
|
71
68
|
- - "~>"
|
72
69
|
- !ruby/object:Gem::Version
|
73
70
|
version: '3.8'
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 3.8.0
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
75
|
name: rake
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
|
-
- - ">="
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: 12.0.0
|
81
78
|
- - "~>"
|
82
79
|
- !ruby/object:Gem::Version
|
83
80
|
version: '12.0'
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 12.0.0
|
84
84
|
type: :development
|
85
85
|
prerelease: false
|
86
86
|
version_requirements: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - ">="
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: 12.0.0
|
91
88
|
- - "~>"
|
92
89
|
- !ruby/object:Gem::Version
|
93
90
|
version: '12.0'
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 12.0.0
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: pry
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,7 +132,7 @@ files:
|
|
132
132
|
- lib/jbuilder/pagination/exceptions/unpageable_resource_error.rb
|
133
133
|
- lib/jbuilder/pagination/pages.rb
|
134
134
|
- lib/jbuilder/pagination/version.rb
|
135
|
-
homepage: https://github.com/
|
135
|
+
homepage: https://github.com/IlluminusLimited/jbuilder_pagination_plus
|
136
136
|
licenses:
|
137
137
|
- MIT
|
138
138
|
metadata: {}
|
@@ -151,8 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
requirements: []
|
154
|
-
|
155
|
-
rubygems_version: 2.7.8
|
154
|
+
rubygems_version: 3.1.2
|
156
155
|
signing_key:
|
157
156
|
specification_version: 4
|
158
157
|
summary: Jbuilder extension to allows pagination according to JSON API format
|