Skip to content

Commit

Permalink
Merge pull request #3 from socio-labs/feature/pagination_params
Browse files Browse the repository at this point in the history
Feature/pagination params
  • Loading branch information
metekabak committed Jul 5, 2021
2 parents 7109b99 + 8ca579b commit 9bb304a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 22 deletions.
28 changes: 23 additions & 5 deletions lib/jsonapi/pagination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ module Pagination
private
# Default number of items per page.
JSONAPI_PAGE_SIZE = ENV.fetch('PAGINATION_LIMIT') { 30 }
# Default number of items per page.
PAGINATION_IGNORE_KEYS = %i[total_count total_page]

# Applies pagination to a set of resources
#
# Ex.: `GET /resource?page[number]=2&page[size]=10`
#
# @return [ActiveRecord::Base] a collection of resources
def jsonapi_paginate(resources)
def jsonapi_paginate(resources, options = {})
offset, limit, _ = jsonapi_pagination_params

if resources.respond_to?(:offset)
Expand All @@ -23,6 +25,13 @@ def jsonapi_paginate(resources)
resources.instance_variable_set(:@original_size, original_size)
end

if options[:total_count]
resources.instance_variable_set(
:@_predefined_total_count,
options[:total_count]
)
end

block_given? ? yield(resources) : resources
end

Expand All @@ -44,18 +53,21 @@ def jsonapi_pagination(resources)
original_url = '?'

pagination.each do |page_name, number|
next if [:total_count, :total_page].include?(page_name)
next if PAGINATION_IGNORE_KEYS.include?(page_name)

original_params[:page][:number] = number
links[page_name] = number.nil? ? nil : (original_url + CGI.unescape(original_params.to_query))
links[page_name] = number.nil? ? nil : (
original_url + CGI.unescape(original_params.to_query)
)
end

links
end

# Generates pagination numbers
#
# @return [Hash] with the first, previous, next, current, last page numbers
# @return [Hash] with the first, previous, next, current, last page,
# total_count, total_page numbers
def jsonapi_pagination_builder(resources)
return @_numbers if @_numbers
return {} unless JSONAPI::Rails.is_collection?(resources)
Expand All @@ -70,7 +82,10 @@ def jsonapi_pagination_builder(resources)
last: nil
}

if resources.respond_to?(:unscope)
total = resources.instance_variable_get(:@_predefined_total_count)
if total
# do nothing for this condition
elsif resources.respond_to?(:unscope)
total = resources.unscope(:limit, :offset, :order).size
else
# Try to fetch the cached size first
Expand Down Expand Up @@ -99,6 +114,9 @@ def jsonapi_pagination_builder(resources)
@_numbers = numbers
end

# Extracts the pagination meta
#
# @return [Hash] with the first, previous, next, current, last page numbers
def jsonapi_pagination_meta(resources)
pagination = jsonapi_pagination_builder(resources)
pagination.slice(:total_count, :total_page)
Expand Down
1 change: 0 additions & 1 deletion lib/jsonapi/rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ def self.add_renderer!
serializer_class.new(resource, options)
)
end

end

# Checks if an object is a collection
Expand Down
2 changes: 1 addition & 1 deletion lib/jsonapi/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module JSONAPI
VERSION = '2.3.0'
VERSION = '2.4.0'
end
4 changes: 2 additions & 2 deletions spec/fetching_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@

response_json['data'].each do |item|
user = users.detect { |u| u.id == item['id'].to_i }
expect(item).to have_attribute('full_name')
.with_value("#{user.first_name} #{user.last_name}")
full_name = "#{user.first_name} #{user.last_name}"
expect(item).to have_attribute('full_name').with_value(full_name)
end
end
end
Expand Down
29 changes: 16 additions & 13 deletions spec/pagination_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ def query_str(parms, page: nil)
expect(response_json).to have_link(:first)
expect(response_json).to have_link(:last)

query = CGI.unescape(params.deep_merge(page: { number: 1 }).to_query)
expect(URI.parse(response_json['links']['current']).query)
.to eq(CGI.unescape(params.deep_merge(page: { number: 1 }).to_query))
.to eq(query)
end

context 'on page 2 out of 3' do
Expand All @@ -76,8 +77,8 @@ def query_str(parms, page: nil)
expect(response_json['data'][0]).to have_id(second_user.id.to_s)

expect(response_json['meta']['pagination']).to eq(
'total_count'=> 3,
'total_page'=> 3
'total_count' => 3,
'total_page' => 3
)
expect(response_json['links']).to eq(
'current' => query_str(params),
Expand All @@ -95,8 +96,8 @@ def query_str(parms, page: nil)
expect(response_json['data'][0]).to have_id(second_user.id.to_s)

expect(response_json['meta']['pagination']).to eq(
'total_count'=> 3,
'total_page'=> 3
'total_count' => 3,
'total_page' => 3
)
expect(response_json['links']).to eq(
'current' => query_str(params),
Expand All @@ -113,10 +114,12 @@ def query_str(parms, page: nil)
expect(response_json).to have_link(:last)

qry = CGI.unescape(params.to_query)
expect(URI.parse(response_json['links']['current']).query).to eq(qry)
expect(URI.parse(response_json['links']['current']).query)
.to eq(qry)

qry = CGI.unescape(params.deep_merge(page: { number: 2 }).to_query)
expect(URI.parse(response_json['links']['current']).query).to eq(qry)
expect(URI.parse(response_json['links']['current']).query)
.to eq(qry)

qry = CGI.unescape(params.deep_merge(page: { number: 1 }).to_query)
expect(URI.parse(response_json['links']['prev']).query).to eq(qry)
Expand All @@ -140,8 +143,8 @@ def query_str(parms, page: nil)
expect(response_json['data'].size).to eq(1)

expect(response_json['meta']['pagination']).to eq(
'total_count'=> 3,
'total_page'=> 3
'total_count' => 3,
'total_page' => 3
)
expect(response_json['links']).to eq(
'current' => query_str(params),
Expand Down Expand Up @@ -185,8 +188,8 @@ def query_str(parms, page: nil)
expect(response_json['data'].size).to eq(0)

expect(response_json['meta']['pagination']).to eq(
'total_count'=> 3,
'total_page'=> 3
'total_count' => 3,
'total_page' => 3
)
expect(response_json['links']).to eq(
'current' => query_str(params),
Expand All @@ -203,8 +206,8 @@ def query_str(parms, page: nil)
expect(response_json['data'].size).to eq(0)

expect(response_json['meta']['pagination']).to eq(
'total_count'=> 3,
'total_page'=> 3
'total_count' => 3,
'total_page' => 3
)
expect(response_json['links']).to eq(
'current' => query_str(params),
Expand Down

0 comments on commit 9bb304a

Please sign in to comment.