Skip to content

Commit 33b35b8

Browse files
authored
Merge pull request #107 from StefSchenkelaars/exclude-total
Remove last link header when include total option is false
2 parents 85cadc8 + 58ad95d commit 33b35b8

File tree

7 files changed

+64
-21
lines changed

7 files changed

+64
-21
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ ApiPagination.configure do |config|
5555
config.per_page_param do |params|
5656
params[:page][:size]
5757
end
58+
59+
# Optional: Include the total and last_page link header
60+
# By default, this is set to true
61+
# Note: When using kaminari, this prevents the count call to the database
62+
config.include_total = false
5863
end
5964
```
6065

lib/api-pagination.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def pages_from(collection, options = {})
3030
end
3131

3232
unless collection.last_page? || (ApiPagination.config.paginator == :kaminari && collection.out_of_range?)
33-
pages[:last] = collection.total_pages
33+
pages[:last] = collection.total_pages if ApiPagination.config.include_total
3434
pages[:next] = collection.current_page + 1
3535
end
3636
end
@@ -76,7 +76,7 @@ def pagy_pages_from(pagy)
7676
end
7777

7878
unless pagy.page == pagy.pages
79-
pages[:last] = pagy.pages
79+
pages[:last] = pagy.pages if ApiPagination.config.include_total
8080
pages[:next] = pagy.next
8181
end
8282
end
@@ -90,7 +90,9 @@ def paginate_with_kaminari(collection, options, paginate_array_options = {})
9090
end
9191

9292
collection = Kaminari.paginate_array(collection, paginate_array_options) if collection.is_a?(Array)
93-
[collection.page(options[:page]).per(options[:per_page]), nil]
93+
collection = collection.page(options[:page]).per(options[:per_page])
94+
collection.without_count if !collection.is_a?(Array) && !ApiPagination.config.include_total
95+
[collection, nil]
9496
end
9597

9698
def paginate_with_will_paginate(collection, options)

spec/api-pagination_spec.rb

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,45 @@
22

33
describe ApiPagination do
44
let(:collection) {(1..100).to_a}
5+
let(:active_record_relation) {double("ActiveRecord_Relation").as_null_object}
56
let(:paginate_array_options) {{ total_count: 1000 }}
67

78
describe "#paginate" do
89
if ENV['PAGINATOR'].to_sym == :kaminari
910
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-
)
11+
describe '.paginate' do
12+
it 'should accept paginate_array_options option' do
13+
expect(Kaminari).to receive(:paginate_array)
14+
.with(collection, paginate_array_options)
15+
.and_call_original
16+
17+
ApiPagination.paginate(
18+
collection,
19+
{
20+
per_page: 30,
21+
paginate_array_options: paginate_array_options
22+
}
23+
)
24+
end
25+
26+
context 'configured not to include the total' do
27+
before { ApiPagination.config.include_total = false }
28+
29+
context 'and paginating an array' do
30+
it 'should not call without_count on the collection' do
31+
expect(collection).to_not receive :without_count
32+
ApiPagination.paginate(collection)
33+
end
34+
end
35+
context 'and paginating an active record relation' do
36+
it 'should call without_count on the relation' do
37+
expect(active_record_relation).to receive :without_count
38+
ApiPagination.paginate(active_record_relation)
39+
end
40+
end
41+
42+
after { ApiPagination.config.include_total = true }
43+
end
2244
end
2345

2446
describe '.pages_from' do

spec/grape_spec.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
describe NumbersAPI do
88
describe 'GET #index' do
9-
let(:links) { last_response.headers['Link'].split(', ') }
9+
let(:link) { last_response.headers['Link'] }
10+
let(:links) { link.split(', ') }
1011
let(:total) { last_response.headers['Total'].to_i }
1112
let(:per_page) { last_response.headers['Per-Page'].to_i }
1213

@@ -139,6 +140,12 @@
139140
expect(last_response.header['Total']).to be_nil
140141
end
141142

143+
it 'should not include a link with rel "last"' do
144+
get '/numbers', count: 100
145+
146+
expect(link).to_not include('rel="last"')
147+
end
148+
142149
after { ApiPagination.config.include_total = true }
143150
end
144151

spec/rails_spec.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
before { request.host = 'example.org' }
99

1010
describe 'GET #index' do
11-
let(:links) { response.headers['Link'].split(', ') }
11+
let(:link) { response.headers['Link'] }
12+
let(:links) { link.split(', ') }
1213
let(:total) { response.headers['Total'].to_i }
1314
let(:per_page) { response.headers['Per-Page'].to_i }
1415

@@ -134,6 +135,12 @@
134135
expect(response.header['Total']).to be_nil
135136
end
136137

138+
it 'should not include a link with rel "last"' do
139+
get :index, params: { count: 100 }
140+
141+
expect(link).to_not include('rel="last"')
142+
end
143+
137144
after { ApiPagination.config.include_total = true }
138145
end
139146

spec/support/shared_examples/first_page.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
shared_examples 'an endpoint with a first page' do
22
it 'should not give a link with rel "first"' do
3-
expect(links).not_to include('rel="first"')
3+
expect(link).not_to include('rel="first"')
44
end
55

66
it 'should not give a link with rel "prev"' do
7-
expect(links).not_to include('rel="prev"')
7+
expect(link).not_to include('rel="prev"')
88
end
99

1010
it 'should give a link with rel "last"' do

spec/support/shared_examples/last_page.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
shared_examples 'an endpoint with a last page' do
22
it 'should not give a link with rel "last"' do
3-
expect(links).not_to include('rel="last"')
3+
expect(link).not_to include('rel="last"')
44
end
55

66
it 'should not give a link with rel "next"' do
7-
expect(links).not_to include('rel="next"')
7+
expect(link).not_to include('rel="next"')
88
end
99

1010
it 'should give a link with rel "first"' do

0 commit comments

Comments
 (0)