Skip to content

Add support for optional param names #56

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

Merged
merged 1 commit into from
Feb 24, 2016
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
.config
.yardoc
.ruby-version
.ruby-gemset
Gemfile.lock
InstalledFiles
_yardoc
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,22 @@ ApiPagination.configure do |config|
# By default, this is set to 'Per-Page'
config.per_page_header = 'X-Per-Page'

# Optional : set this to add a header with the current page number.
# Optional: set this to add a header with the current page number.
config.page_header = 'X-Page'

# Optional: what parameter should be used to set the page option
config.page_param = :page
# or
config.page_param do |params|
params[:page][:number]
end

# Optional: what parameter should be used to set the per page option
config.per_page_param = :per_page
# or
config.per_page_param do |params|
params[:page][:size]
end
end
```

Expand Down
27 changes: 27 additions & 0 deletions lib/api-pagination/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,33 @@ def initialize
@include_total = true
end

['page', 'per_page'].each do |param_name|
method_name = "#{param_name}_param"
instance_variable_name = "@#{method_name}"

define_method method_name do |params = nil, &block|
if block.is_a?(Proc)
instance_variable_set(instance_variable_name, block)
return
end

if instance_variable_get(instance_variable_name).nil?
# use :page & :per_page by default
instance_variable_set(instance_variable_name, (lambda { |p| p[param_name.to_sym] }))
end

instance_variable_get(instance_variable_name).call(params)
end

define_method "#{method_name}=" do |param|
if param.is_a?(Symbol) || param.is_a?(String)
instance_variable_set(instance_variable_name, (lambda { |params| params[param] }))
else
raise ArgumentError, "Cannot set page_param option"
end
end
end

def paginator
@paginator || set_paginator
end
Expand Down
5 changes: 3 additions & 2 deletions lib/grape/pagination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ module Pagination
def self.included(base)
Grape::Endpoint.class_eval do
def paginate(collection)
per_page = params[:per_page] || route_setting(:per_page)
per_page = ApiPagination.config.per_page_param(params) || route_setting(:per_page)

options = {
:page => params[:page],
:page => ApiPagination.config.page_param(params),
:per_page => [per_page, route_setting(:max_per_page)].compact.min
}
collection = ApiPagination.paginate(collection, options)
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,8 +25,11 @@ def paginate_with(collection)

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

Expand Down
77 changes: 77 additions & 0 deletions spec/rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,82 @@

after { ApiPagination.config.include_total = true }
end

context 'custom page param' do
context 'page_param as a symbol' do
before do
ApiPagination.config.page_param = :foo
ApiPagination.config.page_header = 'Page'
end

after do
ApiPagination.config.page_param = :page
ApiPagination.config.page_header = nil
end

it 'should work' do
get :index, :foo => 2, :count => 100

expect(response.header['Page']).to eq('2')
end
end

context 'page_param as a block' do
before do
ApiPagination.config.page_param do |params|
params[:foo][:bar]
end

ApiPagination.config.page_header = 'Page'
end

after do
ApiPagination.config.page_param = :page
ApiPagination.config.page_header = nil
end

it 'should work' do
get :index, :foo => { :bar => 2 }, :count => 100

expect(response.header['Page']).to eq('2')
end
end
end

context 'custom per_page param' do
context 'per_page_param as a symbol' do
before do
ApiPagination.config.per_page_param = :foo
end

after do
ApiPagination.config.per_page_param = :per_page
end

it 'should work' do
get :index_with_no_per_page, :foo => 2, :count => 100

expect(response.header['Per-Page']).to eq('2')
end
end

context 'page_param as a block' do
before do
ApiPagination.config.per_page_param do |params|
params[:foo][:bar]
end
end

after do
ApiPagination.config.per_page_param = :per_page
end

it 'should work' do
get :index_with_no_per_page, :foo => { :bar => 2 }, :count => 100

expect(response.header['Per-Page']).to eq('2')
end
end
end
end
end
9 changes: 9 additions & 0 deletions spec/support/numbers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def teardown(*methods)
Rails.application.routes.draw do
resources :numbers, :only => [:index] do
get :index_with_custom_render, on: :collection
get :index_with_no_per_page, on: :collection
end
end

Expand Down Expand Up @@ -76,4 +77,12 @@ def index_with_custom_render

render json: NumbersSerializer.new(numbers)
end

def index_with_no_per_page
total = params.fetch(:count).to_i
numbers = (1..total).to_a
numbers = paginate numbers

render json: NumbersSerializer.new(numbers)
end
end