diff --git a/lib/jsonapi/paginator.rb b/lib/jsonapi/paginator.rb index 53f8fbbe4..d6396b4a9 100644 --- a/lib/jsonapi/paginator.rb +++ b/lib/jsonapi/paginator.rb @@ -31,7 +31,8 @@ def paginator_for(paginator) class OffsetPaginator < JSONAPI::Paginator attr_reader :limit, :offset - def initialize(params) + def initialize(params, options = {}) + @options = options parse_pagination_params(params) verify_pagination_params end @@ -89,15 +90,17 @@ def links_page_params(options = {}) private + attr_reader :options + def parse_pagination_params(params) if params.nil? - @offset = 0 - @limit = JSONAPI.configuration.default_page_size + @offset = default_offset + @limit = default_limit elsif params.is_a?(ActionController::Parameters) - validparams = params.permit(:offset, :limit) + valid_params = params.permit(:offset, :limit) - @offset = validparams[:offset] ? validparams[:offset].to_i : 0 - @limit = validparams[:limit] ? validparams[:limit].to_i : JSONAPI.configuration.default_page_size + @offset = (valid_params[:offset] || default_offset).to_i + @limit = (valid_params[:limit] || default_limit).to_i else fail JSONAPI::Exceptions::InvalidPageObject.new end @@ -117,12 +120,21 @@ def verify_pagination_params fail JSONAPI::Exceptions::InvalidPageValue.new(:offset, @offset) end end + + def default_offset + options.try(:[], :offset) || 0 + end + + def default_limit + options.try(:[], :limit) || JSONAPI.configuration.default_page_size + end end class PagedPaginator < JSONAPI::Paginator attr_reader :size, :number - def initialize(params) + def initialize(params, options) + @options = options parse_pagination_params(params) verify_pagination_params end @@ -177,18 +189,20 @@ def links_page_params(options = {}) private + attr_reader :options + def parse_pagination_params(params) if params.nil? - @number = 1 - @size = JSONAPI.configuration.default_page_size + @number = default_page_number + @size = default_page_size elsif params.is_a?(ActionController::Parameters) - validparams = params.permit(:number, :size) + valid_params = params.permit(:number, :size) - @size = validparams[:size] ? validparams[:size].to_i : JSONAPI.configuration.default_page_size - @number = validparams[:number] ? validparams[:number].to_i : 1 + @number = (valid_params[:number] || default_page_number).to_i + @size = (valid_params[:size] || default_page_size).to_i else - @size = JSONAPI.configuration.default_page_size @number = params.to_i + @size = default_page_size end rescue ActionController::UnpermittedParameters => e raise JSONAPI::Exceptions::PageParametersNotAllowed.new(e.params) @@ -206,4 +220,12 @@ def verify_pagination_params fail JSONAPI::Exceptions::InvalidPageValue.new(:number, @number) end end + + def default_page_size + options.try(:[], :default_page_size) || JSONAPI.configuration.default_page_size + end + + def default_page_number + options.try(:[], :default_page_number) || 1 + end end diff --git a/lib/jsonapi/request_parser.rb b/lib/jsonapi/request_parser.rb index a80b971ac..1e472b314 100644 --- a/lib/jsonapi/request_parser.rb +++ b/lib/jsonapi/request_parser.rb @@ -259,7 +259,13 @@ def parse_modify_relationship_action(modification_type, params, resource_klass) def parse_pagination(resource_klass, page) paginator_name = resource_klass._paginator - JSONAPI::Paginator.paginator_for(paginator_name).new(page) unless paginator_name == :none + return if paginator_name == :none + + options = resource_klass._paginator_options + paginator = JSONAPI::Paginator.paginator_for(paginator_name) + arity = paginator.instance_method(:initialize).arity + + arity == 2 ? paginator.new(page, options) : paginator.new(page) end def parse_fields(resource_klass, fields) diff --git a/lib/jsonapi/resource.rb b/lib/jsonapi/resource.rb index ddd9ae7d2..33642cb6f 100644 --- a/lib/jsonapi/resource.rb +++ b/lib/jsonapi/resource.rb @@ -806,8 +806,13 @@ def _paginator @_paginator ||= JSONAPI.configuration.default_paginator end - def paginator(paginator) + def _paginator_options + @_paginator_options ||= {} + end + + def paginator(paginator, options = {}) @_paginator = paginator + @_paginator_options = options end def _record_accessor