api-pagination 4.7.2 → 4.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|