diff --git a/lib/jsonapi/pagination.rb b/lib/jsonapi/pagination.rb index a98d149..5502e17 100644 --- a/lib/jsonapi/pagination.rb +++ b/lib/jsonapi/pagination.rb @@ -13,14 +13,13 @@ module Pagination def jsonapi_paginate(resources) offset, limit, _ = jsonapi_pagination_params + # Cache the original resources size to be used for pagination meta + @_jsonapi_original_size = resources.size + if resources.respond_to?(:offset) resources = resources.offset(offset).limit(limit) else - original_size = resources.size resources = resources[(offset)..(offset + limit - 1)] || [] - - # Cache the original resources size to be used for pagination meta - resources.instance_variable_set(:@original_size, original_size) end block_given? ? yield(resources) : resources @@ -64,13 +63,7 @@ def jsonapi_pagination_meta(resources) numbers = { current: page } - if resources.respond_to?(:unscope) - total = resources.unscope(:limit, :offset, :order).size - else - # Try to fetch the cached size first - total = resources.instance_variable_get(:@original_size) - total ||= resources.size - end + total = @_jsonapi_original_size last_page = [1, (total.to_f / limit).ceil].max diff --git a/spec/dummy.rb b/spec/dummy.rb index 8f222fd..c2e32ef 100644 --- a/spec/dummy.rb +++ b/spec/dummy.rb @@ -119,6 +119,7 @@ def index result = result.to_a if params[:as_list] jsonapi_paginate(result) do |paginated| + paginated = paginated.to_a if params[:decorate_after_pagination] render jsonapi: paginated end end diff --git a/spec/pagination_spec.rb b/spec/pagination_spec.rb index 622c81e..d417274 100644 --- a/spec/pagination_spec.rb +++ b/spec/pagination_spec.rb @@ -53,11 +53,13 @@ context 'on page 2 out of 3' do let(:as_list) { } + let(:decorate_after_pagination) { } let(:params) do { page: { number: 2, size: 1 }, sort: '-created_at', - as_list: as_list + as_list: as_list, + decorate_after_pagination: decorate_after_pagination }.compact_blank end @@ -80,6 +82,25 @@ end end + context 'when decorating objects after pagination' do + let(:decorate_after_pagination) { true } + + it do + expect(response).to have_http_status(:ok) + expect(response_json['data'].size).to eq(1) + expect(response_json['data'][0]).to have_id(second_user.id.to_s) + + expect(response_json['meta']['pagination']).to eq( + 'current' => 2, + 'first' => 1, + 'prev' => 1, + 'next' => 3, + 'last' => 3, + 'records' => 3 + ) + end + end + it do expect(response).to have_http_status(:ok) expect(response_json['data'].size).to eq(1)