api-pagination 4.7.2 → 4.8.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/lib/api-pagination.rb +45 -3
- data/lib/api-pagination/configuration.rb +15 -6
- data/lib/api-pagination/hooks.rb +5 -3
- data/lib/api-pagination/version.rb +2 -2
- data/lib/grape/pagination.rb +3 -3
- data/lib/rails/pagination.rb +3 -4
- data/spec/api-pagination_spec.rb +33 -45
- data/spec/rails_spec.rb +38 -62
- data/spec/sequel_spec.rb +1 -2
- data/spec/spec_helper.rb +9 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9027303d9da656103e61812aded61149a601a27dbc398d40d44d2952242fbb6d
|
4
|
+
data.tar.gz: 5758331c124689a6160d6b787409bb8abfbba83213e201289c227f624afe7db5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ae4651a31cfbe45a02ffc9da7376c30ef5400d30265528de8f39130924fbef327d7158aedfe21fe7c24899c3632a14161bfc4392f8ab69fc167c21d4de608be
|
7
|
+
data.tar.gz: 842bb2e7b03046cbacfbfed1dc8ea6c4ebc435f7a91423d98f844dde5a2128573cd21bda81d5813a8e813abfb0154f22e0fc0436033923ddd4af04f96888f0ea
|
data/lib/api-pagination.rb
CHANGED
@@ -9,6 +9,8 @@ module ApiPagination
|
|
9
9
|
options[:per_page] = options[:per_page].to_i
|
10
10
|
|
11
11
|
case ApiPagination.config.paginator
|
12
|
+
when :pagy
|
13
|
+
paginate_with_pagy(collection, options)
|
12
14
|
when :kaminari
|
13
15
|
paginate_with_kaminari(collection, options, options[:paginate_array_options] || {})
|
14
16
|
when :will_paginate
|
@@ -18,7 +20,9 @@ module ApiPagination
|
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
def pages_from(collection)
|
23
|
+
def pages_from(collection, options = {})
|
24
|
+
return pagy_pages_from(collection) if collection.is_a?(Pagy)
|
25
|
+
|
22
26
|
{}.tap do |pages|
|
23
27
|
unless collection.first_page?
|
24
28
|
pages[:first] = 1
|
@@ -34,6 +38,7 @@ module ApiPagination
|
|
34
38
|
|
35
39
|
def total_from(collection)
|
36
40
|
case ApiPagination.config.paginator
|
41
|
+
when :pagy then collection.count.to_s
|
37
42
|
when :kaminari then collection.total_count.to_s
|
38
43
|
when :will_paginate then collection.total_entries.to_s
|
39
44
|
end
|
@@ -41,6 +46,41 @@ module ApiPagination
|
|
41
46
|
|
42
47
|
private
|
43
48
|
|
49
|
+
def paginate_with_pagy(collection, options)
|
50
|
+
if Pagy::VARS[:max_per_page] && options[:per_page] > Pagy::VARS[:max_per_page]
|
51
|
+
options[:per_page] = Pagy::VARS[:max_per_page]
|
52
|
+
elsif options[:per_page] <= 0
|
53
|
+
options[:per_page] = Pagy::VARS[:items]
|
54
|
+
end
|
55
|
+
|
56
|
+
pagy = pagy_from(collection, options)
|
57
|
+
collection = if collection.respond_to?(:offset) && collection.respond_to?(:limit)
|
58
|
+
collection.offset(pagy.offset).limit(pagy.items)
|
59
|
+
else
|
60
|
+
collection[pagy.offset, pagy.items]
|
61
|
+
end
|
62
|
+
|
63
|
+
return [collection, pagy]
|
64
|
+
end
|
65
|
+
|
66
|
+
def pagy_from(collection, options)
|
67
|
+
Pagy.new(count: collection.count, items: options[:per_page], page: options[:page])
|
68
|
+
end
|
69
|
+
|
70
|
+
def pagy_pages_from(pagy)
|
71
|
+
{}.tap do |pages|
|
72
|
+
unless pagy.page == 1
|
73
|
+
pages[:first] = 1
|
74
|
+
pages[:prev] = pagy.prev
|
75
|
+
end
|
76
|
+
|
77
|
+
unless pagy.page == pagy.pages
|
78
|
+
pages[:last] = pagy.pages
|
79
|
+
pages[:next] = pagy.next
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
44
84
|
def paginate_with_kaminari(collection, options, paginate_array_options = {})
|
45
85
|
if Kaminari.config.max_per_page && options[:per_page] > Kaminari.config.max_per_page
|
46
86
|
options[:per_page] = Kaminari.config.max_per_page
|
@@ -49,7 +89,7 @@ module ApiPagination
|
|
49
89
|
end
|
50
90
|
|
51
91
|
collection = Kaminari.paginate_array(collection, paginate_array_options) if collection.is_a?(Array)
|
52
|
-
collection.page(options[:page]).per(options[:per_page])
|
92
|
+
[collection.page(options[:page]).per(options[:per_page]), nil]
|
53
93
|
end
|
54
94
|
|
55
95
|
def paginate_with_will_paginate(collection, options)
|
@@ -57,13 +97,15 @@ module ApiPagination
|
|
57
97
|
options[:per_page] = default_per_page_for_will_paginate(collection)
|
58
98
|
end
|
59
99
|
|
60
|
-
if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
|
100
|
+
collection = if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
|
61
101
|
collection.paginate(options[:page], options[:per_page])
|
62
102
|
else
|
63
103
|
supported_options = [:page, :per_page, :total_entries]
|
64
104
|
options = options.dup.keep_if { |k,v| supported_options.include?(k.to_sym) }
|
65
105
|
collection.paginate(options)
|
66
106
|
end
|
107
|
+
|
108
|
+
[collection, nil]
|
67
109
|
end
|
68
110
|
|
69
111
|
def get_default_per_page_for_kaminari(collection)
|
@@ -55,6 +55,8 @@ module ApiPagination
|
|
55
55
|
|
56
56
|
def paginator=(paginator)
|
57
57
|
case paginator.to_sym
|
58
|
+
when :pagy
|
59
|
+
use_pagy
|
58
60
|
when :kaminari
|
59
61
|
use_kaminari
|
60
62
|
when :will_paginate
|
@@ -67,11 +69,12 @@ module ApiPagination
|
|
67
69
|
private
|
68
70
|
|
69
71
|
def set_paginator
|
70
|
-
|
72
|
+
conditions = [defined?(Pagy), defined?(Kaminari), defined?(WillPaginate::CollectionMethods)]
|
73
|
+
if conditions.compact.size > 1
|
71
74
|
Kernel.warn <<-WARNING
|
72
|
-
Warning: api-pagination relies on
|
73
|
-
currently active. If possible, you should remove one or the other. If
|
74
|
-
you _must_ configure api-pagination on your own. For example:
|
75
|
+
Warning: api-pagination relies on Pagy, Kaminari, or WillPaginate, but more than
|
76
|
+
one are currently active. If possible, you should remove one or the other. If
|
77
|
+
you can't, you _must_ configure api-pagination on your own. For example:
|
75
78
|
|
76
79
|
ApiPagination.configure do |config|
|
77
80
|
config.paginator = :kaminari
|
@@ -86,13 +89,19 @@ Kaminari.configure do |config|
|
|
86
89
|
end
|
87
90
|
|
88
91
|
WARNING
|
92
|
+
elsif defined?(Pagy)
|
93
|
+
use_pagy
|
89
94
|
elsif defined?(Kaminari)
|
90
|
-
|
95
|
+
use_kaminari
|
91
96
|
elsif defined?(WillPaginate::CollectionMethods)
|
92
|
-
|
97
|
+
use_will_paginate
|
93
98
|
end
|
94
99
|
end
|
95
100
|
|
101
|
+
def use_pagy
|
102
|
+
@paginator = :pagy
|
103
|
+
end
|
104
|
+
|
96
105
|
def use_kaminari
|
97
106
|
require 'kaminari/models/array_extension'
|
98
107
|
@paginator = :kaminari
|
data/lib/api-pagination/hooks.rb
CHANGED
@@ -4,14 +4,16 @@ if defined?(Grape::API)
|
|
4
4
|
Grape::API.send(:include, Grape::Pagination)
|
5
5
|
end
|
6
6
|
|
7
|
+
begin; require 'pagy'; rescue LoadError; end
|
7
8
|
begin; require 'kaminari'; rescue LoadError; end
|
8
9
|
begin; require 'will_paginate'; rescue LoadError; end
|
9
10
|
|
10
|
-
unless defined?(Kaminari) || defined?(WillPaginate::CollectionMethods)
|
11
|
+
unless defined?(Pagy) || defined?(Kaminari) || defined?(WillPaginate::CollectionMethods)
|
11
12
|
Kernel.warn <<-WARNING.gsub(/^\s{4}/, '')
|
12
|
-
Warning: api-pagination relies on either Kaminari or WillPaginate.
|
13
|
-
install
|
13
|
+
Warning: api-pagination relies on either Pagy, Kaminari, or WillPaginate.
|
14
|
+
Please install a paginator by adding one of the following to your Gemfile:
|
14
15
|
|
16
|
+
gem 'pagy'
|
15
17
|
gem 'kaminari'
|
16
18
|
gem 'will_paginate'
|
17
19
|
WARNING
|
data/lib/grape/pagination.rb
CHANGED
@@ -9,11 +9,11 @@ module Grape
|
|
9
9
|
:page => ApiPagination.config.page_param(params),
|
10
10
|
:per_page => [per_page, route_setting(:max_per_page)].compact.min
|
11
11
|
}
|
12
|
-
collection = ApiPagination.paginate(collection, options)
|
12
|
+
collection, pagy = ApiPagination.paginate(collection, options)
|
13
13
|
|
14
14
|
links = (header['Link'] || "").split(',').map(&:strip)
|
15
15
|
url = request.url.sub(/\?.*$/, '')
|
16
|
-
pages = ApiPagination.pages_from(collection)
|
16
|
+
pages = ApiPagination.pages_from(pagy || collection, options)
|
17
17
|
|
18
18
|
pages.each do |k, v|
|
19
19
|
old_params = Rack::Utils.parse_nested_query(request.query_string)
|
@@ -27,7 +27,7 @@ module Grape
|
|
27
27
|
include_total = ApiPagination.config.include_total
|
28
28
|
|
29
29
|
header 'Link', links.join(', ') unless links.empty?
|
30
|
-
header total_header, ApiPagination.total_from(collection).to_s if include_total
|
30
|
+
header total_header, ApiPagination.total_from(pagy || collection).to_s if include_total
|
31
31
|
header per_page_header, options[:per_page].to_s
|
32
32
|
header page_header, options[:page].to_s unless page_header.nil?
|
33
33
|
|
data/lib/rails/pagination.rb
CHANGED
@@ -27,11 +27,11 @@ module Rails
|
|
27
27
|
options[:page] = ApiPagination.config.page_param(params)
|
28
28
|
options[:per_page] ||= ApiPagination.config.per_page_param(params)
|
29
29
|
|
30
|
-
collection = ApiPagination.paginate(collection, options)
|
30
|
+
collection, pagy = ApiPagination.paginate(collection, options)
|
31
31
|
|
32
32
|
links = (headers['Link'] || '').split(',').map(&:strip)
|
33
33
|
url = base_url + request.path_info
|
34
|
-
pages = ApiPagination.pages_from(collection)
|
34
|
+
pages = ApiPagination.pages_from(pagy || collection, options)
|
35
35
|
|
36
36
|
pages.each do |k, v|
|
37
37
|
new_params = request.query_parameters.merge(:page => v)
|
@@ -46,7 +46,7 @@ module Rails
|
|
46
46
|
headers['Link'] = links.join(', ') unless links.empty?
|
47
47
|
headers[per_page_header] = options[:per_page].to_s
|
48
48
|
headers[page_header] = options[:page].to_s unless page_header.nil?
|
49
|
-
headers[total_header] = total_count(collection, options).to_s if include_total
|
49
|
+
headers[total_header] = total_count(pagy || collection, options).to_s if include_total
|
50
50
|
|
51
51
|
return collection
|
52
52
|
end
|
@@ -62,6 +62,5 @@ module Rails
|
|
62
62
|
def base_url
|
63
63
|
ApiPagination.config.base_url || request.base_url
|
64
64
|
end
|
65
|
-
|
66
65
|
end
|
67
66
|
end
|
data/spec/api-pagination_spec.rb
CHANGED
@@ -5,60 +5,48 @@ describe ApiPagination do
|
|
5
5
|
let(:paginate_array_options) {{ total_count: 1000 }}
|
6
6
|
|
7
7
|
describe "#paginate" do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
collection,
|
24
|
-
{
|
25
|
-
per_page: 30,
|
26
|
-
paginate_array_options: paginate_array_options
|
27
|
-
}
|
28
|
-
)
|
29
|
-
end
|
8
|
+
if ENV['PAGINATOR'].to_sym == :kaminari
|
9
|
+
context 'Using kaminari' do
|
10
|
+
it 'should accept paginate_array_options option' do
|
11
|
+
expect(Kaminari).to receive(:paginate_array)
|
12
|
+
.with(collection, paginate_array_options)
|
13
|
+
.and_call_original
|
14
|
+
|
15
|
+
ApiPagination.paginate(
|
16
|
+
collection,
|
17
|
+
{
|
18
|
+
per_page: 30,
|
19
|
+
paginate_array_options: paginate_array_options
|
20
|
+
}
|
21
|
+
)
|
22
|
+
end
|
30
23
|
|
31
|
-
|
32
|
-
|
24
|
+
describe '.pages_from' do
|
25
|
+
subject { described_class.pages_from(collection) }
|
33
26
|
|
34
|
-
|
35
|
-
|
27
|
+
context 'on empty collection' do
|
28
|
+
let(:collection) { ApiPagination.paginate([], page: 1).first }
|
36
29
|
|
37
|
-
|
30
|
+
it { is_expected.to be_empty }
|
31
|
+
end
|
38
32
|
end
|
39
33
|
end
|
40
34
|
end
|
41
35
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'passing in total_entries in options' do
|
52
|
-
it 'should set total_entries using the passed in value' do
|
53
|
-
paginated_collection = ApiPagination.paginate(collection, total_entries: 3000)
|
54
|
-
expect(paginated_collection.total_entries).to eq(3000)
|
36
|
+
if ENV['PAGINATOR'].to_sym == :will_paginate
|
37
|
+
context 'Using will_paginate' do
|
38
|
+
context 'passing in total_entries in options' do
|
39
|
+
it 'should set total_entries using the passed in value' do
|
40
|
+
paginated_collection = ApiPagination.paginate(collection, total_entries: 3000).first
|
41
|
+
expect(paginated_collection.total_entries).to eq(3000)
|
42
|
+
end
|
55
43
|
end
|
56
|
-
end
|
57
44
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
45
|
+
context 'passing in collection only' do
|
46
|
+
it 'should set total_entries using the size of the collection ' do
|
47
|
+
paginated_collection = ApiPagination.paginate(collection).first
|
48
|
+
expect(paginated_collection.total_entries).to eq(100)
|
49
|
+
end
|
62
50
|
end
|
63
51
|
end
|
64
52
|
end
|
data/spec/rails_spec.rb
CHANGED
@@ -214,8 +214,11 @@ describe NumbersController, :type => :controller do
|
|
214
214
|
end
|
215
215
|
end
|
216
216
|
|
217
|
-
|
218
|
-
|
217
|
+
if ApiPagination.config.paginator.to_sym == :kaminari
|
218
|
+
context 'paginate array options' do
|
219
|
+
let(:paginate_array_total_count) { 300 }
|
220
|
+
let(:total_header) { 300 }
|
221
|
+
let(:count) { 50 }
|
219
222
|
let(:params) do
|
220
223
|
{
|
221
224
|
paginate_array_total_count: paginate_array_total_count,
|
@@ -223,84 +226,57 @@ describe NumbersController, :type => :controller do
|
|
223
226
|
}
|
224
227
|
end
|
225
228
|
|
226
|
-
|
229
|
+
it 'has a properly set Total header' do
|
227
230
|
get :index_with_paginate_array_options, params: params
|
228
231
|
|
229
232
|
expect(response.header['Total']).to be_kind_of(String)
|
230
233
|
expect(response.header['Total'].to_i).to eq total_header
|
231
234
|
end
|
232
235
|
end
|
233
|
-
|
234
|
-
context 'kaminari' do
|
235
|
-
around do |example|
|
236
|
-
paginator = ApiPagination.config.paginator
|
237
|
-
ApiPagination.config.paginator = :kaminari
|
238
|
-
example.run
|
239
|
-
ApiPagination.config.paginator = paginator
|
240
|
-
end
|
241
|
-
|
242
|
-
it_should_behave_like 'properly set Total header' do
|
243
|
-
let(:paginate_array_total_count) { 300 }
|
244
|
-
let(:total_header) { 300 }
|
245
|
-
let(:count) { 50 }
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
context 'will_paginate' do
|
250
|
-
around do |example|
|
251
|
-
paginator = ApiPagination.config.paginator
|
252
|
-
ApiPagination.config.paginator = :will_paginate
|
253
|
-
example.run
|
254
|
-
ApiPagination.config.paginator = paginator
|
255
|
-
end
|
256
|
-
|
257
|
-
it_should_behave_like 'properly set Total header' do
|
258
|
-
let(:paginate_array_total_count) { 300 }
|
259
|
-
let(:total_header) { 50 }
|
260
|
-
let(:count) { 50 }
|
261
|
-
end
|
262
|
-
end
|
263
236
|
end
|
264
237
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
238
|
+
if [:will_paginate, :kaminari].include?(ApiPagination.config.paginator.to_sym)
|
239
|
+
context 'default per page in model' do
|
240
|
+
before do
|
241
|
+
class Fixnum
|
242
|
+
@default_per_page = 6
|
243
|
+
@per_page = 6
|
270
244
|
|
271
|
-
|
272
|
-
|
245
|
+
class << self
|
246
|
+
attr_accessor :default_per_page, :per_page
|
247
|
+
end
|
273
248
|
end
|
274
249
|
end
|
275
|
-
end
|
276
250
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
251
|
+
after do
|
252
|
+
class Fixnum
|
253
|
+
@default_per_page = 25
|
254
|
+
@per_page = 25
|
255
|
+
end
|
281
256
|
end
|
282
|
-
end
|
283
257
|
|
284
|
-
|
285
|
-
|
258
|
+
it 'should use default per page from model' do
|
259
|
+
get :index_with_no_per_page, params: {count: 100}
|
286
260
|
|
287
|
-
|
288
|
-
end
|
289
|
-
|
290
|
-
it 'should not fail if model does not respond to per page' do
|
291
|
-
class Fixnum
|
292
|
-
@default_per_page = nil
|
293
|
-
@per_page = nil
|
261
|
+
expect(response.header['Per-Page']).to eq('6')
|
294
262
|
end
|
295
263
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
when :kaminari then Kaminari.config.default_per_page.to_s
|
301
|
-
when :will_paginate then WillPaginate.per_page.to_s
|
264
|
+
it 'should not fail if model does not respond to per page' do
|
265
|
+
class Fixnum
|
266
|
+
@default_per_page = nil
|
267
|
+
@per_page = nil
|
302
268
|
end
|
303
|
-
|
269
|
+
|
270
|
+
get :index_with_no_per_page, params: {count: 100}
|
271
|
+
|
272
|
+
expect(response.header['Per-Page']).to eq(
|
273
|
+
case ApiPagination.config.paginator
|
274
|
+
when :pagy then Pagy::VARS[:items].to_s
|
275
|
+
when :kaminari then Kaminari.config.default_per_page.to_s
|
276
|
+
when :will_paginate then WillPaginate.per_page.to_s
|
277
|
+
end
|
278
|
+
)
|
279
|
+
end
|
304
280
|
end
|
305
281
|
end
|
306
282
|
end
|
data/spec/sequel_spec.rb
CHANGED
@@ -23,9 +23,8 @@ if ApiPagination.config.paginator == :will_paginate
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'returns a Sequel::Dataset' do
|
26
|
-
collection = ApiPagination.paginate(people)
|
26
|
+
collection = ApiPagination.paginate(people).first
|
27
27
|
expect(collection.kind_of?(Sequel::Dataset)).to be_truthy
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
data/spec/spec_helper.rb
CHANGED
@@ -3,14 +3,20 @@ require 'support/numbers_api'
|
|
3
3
|
require 'api-pagination'
|
4
4
|
|
5
5
|
if ENV['PAGINATOR'].nil?
|
6
|
-
warn
|
7
|
-
|
6
|
+
warn <<-WARNING
|
7
|
+
No PAGINATOR set. Defaulting to pagy.
|
8
|
+
|
9
|
+
To test against kaminari, run `PAGINATOR=kaminari bundle exec rspec`
|
10
|
+
To test against will_paginate, run `PAGINATOR=will_paginate bundle exec rspec`
|
11
|
+
WARNING
|
12
|
+
|
13
|
+
ENV['PAGINATOR'] = 'pagy'
|
8
14
|
end
|
9
15
|
|
10
16
|
require ENV['PAGINATOR']
|
11
17
|
ApiPagination.config.paginator = ENV['PAGINATOR'].to_sym
|
12
18
|
|
13
|
-
require 'will_paginate/array'
|
19
|
+
require 'will_paginate/array' if ENV['PAGINATOR'].to_sym == :will_paginate
|
14
20
|
|
15
21
|
RSpec.configure do |config|
|
16
22
|
config.include Rack::Test::Methods
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api-pagination
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Celis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|