diff --git a/lib/jsonapi/utils/response/formatters.rb b/lib/jsonapi/utils/response/formatters.rb index 055b026..c6e39f4 100644 --- a/lib/jsonapi/utils/response/formatters.rb +++ b/lib/jsonapi/utils/response/formatters.rb @@ -263,7 +263,7 @@ def get_source_relationship(options) # @api private def result_options(records, options) {}.tap do |data| - if JSONAPI.configuration.default_paginator != :none && + if apply_pagination?(options) && JSONAPI.configuration.top_level_links_include_pagination data[:pagination_params] = pagination_params(records, options) end @@ -273,7 +273,7 @@ def result_options(records, options) end if JSONAPI.configuration.top_level_meta_include_page_count - data[:page_count] = page_count_for(data[:record_count]) + data[:page_count] = apply_pagination?(options) ? page_count_for(data[:record_count]) : 1 end end end diff --git a/lib/jsonapi/utils/support/pagination.rb b/lib/jsonapi/utils/support/pagination.rb index c8f1eaf..aa35bca 100644 --- a/lib/jsonapi/utils/support/pagination.rb +++ b/lib/jsonapi/utils/support/pagination.rb @@ -62,16 +62,21 @@ def record_count_for(records, options) # # @api private def paginator - @paginator ||= paginator_klass.new(page_params) + @paginator ||= begin + paginator_klass = "#{resource_paginator_name}_paginator".classify.constantize + paginator_klass.new(page_params) + end end - # Return the paginator class to be used in the response's pagination. + # Return the name of the resource's paginator. + # Points to default paginator unless paginator explicitly set on resource. # - # @return [Paginator] + # @return [Symbol] + # e.g.: :paged or :offset # # @api private - def paginator_klass - "#{JSONAPI.configuration.default_paginator}_paginator".classify.constantize + def resource_paginator_name + @resource_paginator_name ||= @request.resource_klass._paginator end # Check whether pagination should be applied to the response. @@ -80,8 +85,7 @@ def paginator_klass # # @api private def apply_pagination?(options) - JSONAPI.configuration.default_paginator != :none && - (options[:paginate].nil? || options[:paginate]) + resource_paginator_name != :none && options[:paginate] != false end # Creates an instance of ActionController::Parameters for page params. @@ -121,7 +125,7 @@ def paginate_with(kind) # # @api private def pagination_range - case JSONAPI.configuration.default_paginator + case resource_paginator_name when :paged number = page_params['number'].to_i.nonzero? || 1 size = page_params['size'].to_i.nonzero? || JSONAPI.configuration.default_page_size diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 68e08ef..a228169 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -79,9 +79,9 @@ end end - context 'when using custom global paginator' do + context 'when using custom paginator' do before(:all) do - JSONAPI.configuration.default_paginator = :custom_offset + PostResource.paginator :custom_offset end let(:params) { { user_id: parent_id, page: { offset: offset, limit: limit } } } diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 56786ef..a9800e6 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -101,7 +101,7 @@ context 'with "page"' do context 'when using "paged" paginator' do before(:all) do - JSONAPI.configuration.default_paginator = :paged + UserResource.paginator :paged end context 'at the first page' do @@ -183,7 +183,7 @@ context 'when using "offset" paginator' do before(:all) do - JSONAPI.configuration.default_paginator = :offset + UserResource.paginator :offset end context 'at the first page' do @@ -246,9 +246,9 @@ end end - context 'when using custom global paginator' do + context 'when using custom paginator' do before(:all) do - JSONAPI.configuration.default_paginator = :custom_offset + UserResource.paginator :custom_offset end context 'at the first page' do @@ -310,6 +310,24 @@ end end end + + context 'without pagination' do + before(:all) do + UserResource.paginator :none + end + + it 'returns all results without pagination links' do + get :index, params: { page: { offset: 0, limit: 2 } } + + expect(response).to have_http_status :ok + expect(response).to have_primary_data('users') + expect(data.size).to eq(User.count) + expect(response).to have_meta_record_count(User.count) + + expect(json.dig('meta', 'page_count')).to eq(1) + expect(json.dig('links')).not_to be_present + end + end end context 'with "sort"' do diff --git a/spec/jsonapi/utils/support/pagination_spec.rb b/spec/jsonapi/utils/support/pagination_spec.rb index c1b2632..a1a2b2f 100644 --- a/spec/jsonapi/utils/support/pagination_spec.rb +++ b/spec/jsonapi/utils/support/pagination_spec.rb @@ -77,7 +77,7 @@ end end - describe '#count_pages_for' do + describe '#page_count_for' do shared_examples_for 'counting pages' do it 'returns the correct page count' do allow(subject).to receive(:page_params).and_return(page_params) @@ -164,4 +164,39 @@ expect(subject.send(:distinct_count_sql, records)).to eq('DISTINCT foos.id') end end + + describe '#apply_pagination?' do + shared_examples_for 'checking pagination' do + it 'returns whether to apply pagination' do + allow(subject).to receive(:resource_paginator_name).and_return(paginator) + expect(subject.send(:apply_pagination?, options)).to eq(apply) + end + end + + context 'with paged paginator' do + let(:paginator) { :paged } + let(:apply) { true } + it_behaves_like 'checking pagination' + end + + context 'without paginator' do + let(:paginator) { :none } + let(:apply) { false } + it_behaves_like 'checking pagination' + end + + context 'when options[:paginate] is false' do + let(:paginator) { :paged } + let(:options) { { paginate: false } } + let(:apply) { false } + it_behaves_like 'checking pagination' + end + + context 'when options[:paginate] is nil' do + let(:paginator) { :paged } + let(:options) { { paginate: nil } } + let(:apply) { true } + it_behaves_like 'checking pagination' + end + end end diff --git a/spec/support/controllers.rb b/spec/support/controllers.rb index d937320..96c57b7 100644 --- a/spec/support/controllers.rb +++ b/spec/support/controllers.rb @@ -14,7 +14,7 @@ def index jsonapi_render json: @user.posts, options: { count: 100 } end - # GET /users/:user_id//index_with_hash + # GET /users/:user_id/index_with_hash def index_with_hash @posts = { data: [ { id: 1, title: 'Lorem Ipsum', body: 'Body 4' },