Skip to content

Adding support for a max_per_page parameter. #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lib/api-pagination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ def paginate(collection, options = {})

case ApiPagination.paginator
when :kaminari
if Kaminari.config.max_per_page && options[:per_page] > Kaminari.config.max_per_page
options[:per_page] = Kaminari.config.max_per_page
max_per_page = (options[:max_per_page] || Kaminari.config.max_per_page).to_i
if options[:max_per_page] && options[:per_page] > max_per_page
options[:per_page] = max_per_page
elsif options[:per_page] <= 0
options[:per_page] = Kaminari.config.default_per_page
end
collection = Kaminari.paginate_array(collection) if collection.is_a?(Array)
collection.page(options[:page]).per(options[:per_page])
when :will_paginate
options[:per_page] = WillPaginate.per_page if options[:per_page] <= 0
max_per_page = options[:max_per_page].to_i
if options[:max_per_page] && options[:per_page] > max_per_page
options[:per_page] = max_per_page
elsif options[:per_page] <= 0
options[:per_page] = WillPaginate.per_page
end

if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
collection.paginate(options[:page], options[:per_page])
Expand Down
16 changes: 10 additions & 6 deletions lib/grape/pagination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ def self.included(base)
def paginate(collection)
options = {
:page => params[:page],
:per_page => (params[:per_page] || settings[:per_page])
:per_page => (params[:per_page] || settings[:per_page]),
:max_per_page => settings[:max_per_page]
}
collection = ApiPagination.paginate(collection, options)

links = (header['Link'] || "").split(',').map(&:strip)
url = request.url.sub(/\?.*$/, '')
pages = ApiPagination.pages_from(collection)

old_params = Rack::Utils.parse_query(request.query_string)
old_params['per_page'] = options[:per_page] if old_params['per_page']

pages.each do |k, v|
old_params = Rack::Utils.parse_query(request.query_string)
new_params = old_params.merge('page' => v)
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
end
Expand All @@ -29,11 +32,12 @@ def paginate(collection)
base.class_eval do
def self.paginate(options = {})
set :per_page, (options[:per_page] || 25)
set :max_per_page, options[:max_per_page]
params do
optional :page, :type => Integer, :default => 1,
:desc => 'Page of results to fetch.'
optional :per_page, :type => Integer,
:desc => 'Number of results to return per page.'
optional :page, :type => Integer, :default => 1,
:desc => 'Page of results to fetch.'
optional :per_page, :type => Integer,
:desc => 'Number of results to return per page.'
end
end
end
Expand Down
7 changes: 5 additions & 2 deletions lib/rails/pagination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@ def paginate_with(collection)

def _paginate_collection(collection, options={})
options = {
:page => params[:page],
:per_page => (options.delete(:per_page) || params[:per_page])
:page => params[:page],
:per_page => (options.delete(:per_page) || params[:per_page]),
:max_per_page => options[:max_per_page]
}
collection = ApiPagination.paginate(collection, options)

links = (headers['Link'] || "").split(',').map(&:strip)
url = request.original_url.sub(/\?.*$/, '')
pages = ApiPagination.pages_from(collection)

request.query_parameters[:per_page] = options[:per_page] if request.query_parameters[:per_page]

pages.each do |k, v|
new_params = request.query_parameters.merge(:page => v)
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
Expand Down
12 changes: 12 additions & 0 deletions spec/grape_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
end
end

context 'with per_page larger than max_per_page' do
before { get :numbers, :count => 100, :per_page => 50 }

it 'should only return max_per_page items' do
expect(last_response.body).to eq('[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]')
end

it 'should correct the per_page parameter in links' do
expect(links).to include('<http://example.org/numbers?count=100&page=5&per_page=20>; rel="last"')
end
end

context 'with existing Link headers' do
before { get :numbers, :count => 30, :with_headers => true }

Expand Down
12 changes: 12 additions & 0 deletions spec/rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
end
end

context 'with per_page larger than max_per_page' do
before { get :index, :count => 100, :per_page => 50 }

it 'should only return max_per_page items' do
expect(response.body).to eq('[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]')
end

it 'should correct the per_page parameter in links' do
expect(links).to include('<http://example.org/numbers?count=100&page=5&per_page=20>; rel="last"')
end
end

context 'with existing Link headers' do
before { get :index, :count => 30, :with_headers => true }

Expand Down
2 changes: 1 addition & 1 deletion spec/support/numbers_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class NumbersAPI < Grape::API
format :json

desc 'Return some paginated set of numbers'
paginate :per_page => 10
paginate :per_page => 10, :max_per_page => 20
params do
requires :count, :type => Integer
optional :with_headers, :default => false, :type => Boolean
Expand Down
2 changes: 1 addition & 1 deletion spec/support/numbers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def index
headers['Link'] = %(<#{numbers_url}?#{query.to_param}>; rel="without")
end

paginate :json => (1..total).to_a, :per_page => 10
paginate :json => (1..total).to_a, :per_page => params[:per_page] || 10, :max_per_page => 20
end

def index_with_custom_render
Expand Down