Skip to content

Commit c5f6e79

Browse files
committed
Merge pull request davidcelis#56 from JiriChara/feature/optional-params
Add support for optional param names
2 parents 3db819f + b81d36e commit c5f6e79

File tree

7 files changed

+137
-5
lines changed

7 files changed

+137
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.config
55
.yardoc
66
.ruby-version
7+
.ruby-gemset
78
Gemfile.lock
89
InstalledFiles
910
_yardoc

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,22 @@ ApiPagination.configure do |config|
4040
# By default, this is set to 'Per-Page'
4141
config.per_page_header = 'X-Per-Page'
4242

43-
# Optional : set this to add a header with the current page number.
43+
# Optional: set this to add a header with the current page number.
4444
config.page_header = 'X-Page'
45+
46+
# Optional: what parameter should be used to set the page option
47+
config.page_param = :page
48+
# or
49+
config.page_param do |params|
50+
params[:page][:number]
51+
end
52+
53+
# Optional: what parameter should be used to set the per page option
54+
config.per_page_param = :per_page
55+
# or
56+
config.per_page_param do |params|
57+
params[:page][:size]
58+
end
4559
end
4660
```
4761

lib/api-pagination/configuration.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,33 @@ def initialize
1919
@include_total = true
2020
end
2121

22+
['page', 'per_page'].each do |param_name|
23+
method_name = "#{param_name}_param"
24+
instance_variable_name = "@#{method_name}"
25+
26+
define_method method_name do |params = nil, &block|
27+
if block.is_a?(Proc)
28+
instance_variable_set(instance_variable_name, block)
29+
return
30+
end
31+
32+
if instance_variable_get(instance_variable_name).nil?
33+
# use :page & :per_page by default
34+
instance_variable_set(instance_variable_name, (lambda { |p| p[param_name.to_sym] }))
35+
end
36+
37+
instance_variable_get(instance_variable_name).call(params)
38+
end
39+
40+
define_method "#{method_name}=" do |param|
41+
if param.is_a?(Symbol) || param.is_a?(String)
42+
instance_variable_set(instance_variable_name, (lambda { |params| params[param] }))
43+
else
44+
raise ArgumentError, "Cannot set page_param option"
45+
end
46+
end
47+
end
48+
2249
def paginator
2350
@paginator || set_paginator
2451
end

lib/grape/pagination.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ module Pagination
33
def self.included(base)
44
Grape::Endpoint.class_eval do
55
def paginate(collection)
6-
per_page = params[:per_page] || route_setting(:per_page)
6+
per_page = ApiPagination.config.per_page_param(params) || route_setting(:per_page)
7+
78
options = {
8-
:page => params[:page],
9+
:page => ApiPagination.config.page_param(params),
910
:per_page => [per_page, route_setting(:max_per_page)].compact.min
1011
}
1112
collection = ApiPagination.paginate(collection, options)

lib/rails/pagination.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ def paginate_with(collection)
2525

2626
def _paginate_collection(collection, options={})
2727
options = {
28-
:page => params[:page],
29-
:per_page => (options.delete(:per_page) || params[:per_page])
28+
:page => ApiPagination.config.page_param(params),
29+
:per_page => (
30+
options.delete(:per_page) ||
31+
ApiPagination.config.per_page_param(params)
32+
)
3033
}
3134
collection = ApiPagination.paginate(collection, options)
3235

spec/rails_spec.rb

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,82 @@
123123

124124
after { ApiPagination.config.include_total = true }
125125
end
126+
127+
context 'custom page param' do
128+
context 'page_param as a symbol' do
129+
before do
130+
ApiPagination.config.page_param = :foo
131+
ApiPagination.config.page_header = 'Page'
132+
end
133+
134+
after do
135+
ApiPagination.config.page_param = :page
136+
ApiPagination.config.page_header = nil
137+
end
138+
139+
it 'should work' do
140+
get :index, :foo => 2, :count => 100
141+
142+
expect(response.header['Page']).to eq('2')
143+
end
144+
end
145+
146+
context 'page_param as a block' do
147+
before do
148+
ApiPagination.config.page_param do |params|
149+
params[:foo][:bar]
150+
end
151+
152+
ApiPagination.config.page_header = 'Page'
153+
end
154+
155+
after do
156+
ApiPagination.config.page_param = :page
157+
ApiPagination.config.page_header = nil
158+
end
159+
160+
it 'should work' do
161+
get :index, :foo => { :bar => 2 }, :count => 100
162+
163+
expect(response.header['Page']).to eq('2')
164+
end
165+
end
166+
end
167+
168+
context 'custom per_page param' do
169+
context 'per_page_param as a symbol' do
170+
before do
171+
ApiPagination.config.per_page_param = :foo
172+
end
173+
174+
after do
175+
ApiPagination.config.per_page_param = :per_page
176+
end
177+
178+
it 'should work' do
179+
get :index_with_no_per_page, :foo => 2, :count => 100
180+
181+
expect(response.header['Per-Page']).to eq('2')
182+
end
183+
end
184+
185+
context 'page_param as a block' do
186+
before do
187+
ApiPagination.config.per_page_param do |params|
188+
params[:foo][:bar]
189+
end
190+
end
191+
192+
after do
193+
ApiPagination.config.per_page_param = :per_page
194+
end
195+
196+
it 'should work' do
197+
get :index_with_no_per_page, :foo => { :bar => 2 }, :count => 100
198+
199+
expect(response.header['Per-Page']).to eq('2')
200+
end
201+
end
202+
end
126203
end
127204
end

spec/support/numbers_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def teardown(*methods)
4141
Rails.application.routes.draw do
4242
resources :numbers, :only => [:index] do
4343
get :index_with_custom_render, on: :collection
44+
get :index_with_no_per_page, on: :collection
4445
end
4546
end
4647

@@ -76,4 +77,12 @@ def index_with_custom_render
7677

7778
render json: NumbersSerializer.new(numbers)
7879
end
80+
81+
def index_with_no_per_page
82+
total = params.fetch(:count).to_i
83+
numbers = (1..total).to_a
84+
numbers = paginate numbers
85+
86+
render json: NumbersSerializer.new(numbers)
87+
end
7988
end

0 commit comments

Comments
 (0)