jbuilder_pagination_plus 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cececb634f26e00fe8a3d65d1144eccef856b13a707529594abde9fc1c27d0da
4
- data.tar.gz: 3ac8472d5ff0b3c2b5fe9aee0d9585db0e8458bd4ff01477ea0ea01c2dbc0515
3
+ metadata.gz: 1a546f0bae157155cea8dafe471cd6e7a44dff00cb9a5823f42b53ef2726974d
4
+ data.tar.gz: dab71bf293fd753e220181d22ab8b9794b45722f532609f55196b442923c1bd6
5
5
  SHA512:
6
- metadata.gz: 7069f7c1bbfdabe4d0ed7c617e30867d59e61d32bfdd911661fbd8b95c05ab0ee2d9a38e80a8b78bd00965ff673e96fc1a66b1dfabb313adc2e61d630d5c9b14
7
- data.tar.gz: c8bce1f559d82dd49a18aa052f5af9692895382331c2cea4e31ddb2f94ea9f5c0849b168f1d59905e2bbd8d3dddd9faff2824ff64d5680d5ecd743bd2fb8386a
6
+ metadata.gz: cb029327b276555c9e1cb4b05fb7600203dcaa25e8a9e7ebf5b62e2cee523f93d5b967cb6e4c3867b4ff9a4de37d8ff5310f4955109a8ab7e500410329cee815
7
+ data.tar.gz: 3eb3fe3370f2980db1930c2b27c01d006611ef4b81e6c0496c66840c512f8431f820246cae2135c68ac66dd7592552630b075efdef1c5533d84a4f46422fa108
@@ -1 +1 @@
1
- ruby-2.5.3
1
+ ruby-2.7.1
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.5.3
3
+ - 2.7.1
4
4
  sudo: false
5
5
  install: bin/setup
6
6
  script:
data/README.md CHANGED
@@ -1,12 +1,15 @@
1
- # Jbuilder Pagination Plus [![Build Status](https://travis-ci.org/PinsterTeam/jbuilder_pagination_plus.svg?branch=master)](https://travis-ci.org/PinsterTeam/jbuilder_pagination_plus) [![Gem Version](https://badge.fury.io/rb/jbuilder_pagination_plus.svg)](https://badge.fury.io/rb/jbuilder_pagination_plus)
1
+ # Jbuilder Pagination Plus [![Build Status](https://travis-ci.org/IlluminusLimited/jbuilder_pagination_plus.svg?branch=master)](https://travis-ci.org/IlluminusLimited/jbuilder_pagination_plus) [![Gem Version](https://badge.fury.io/rb/jbuilder_pagination_plus.svg)](https://badge.fury.io/rb/jbuilder_pagination_plus)
2
2
 
3
- [Jbuilder](https://github.com/rails/jbuilder) extension that makes easier to use pagination according to the [JSON API](http://jsonapi.org/format/#fetching-pagination) conventions.
3
+ [Jbuilder](https://github.com/rails/jbuilder) extension that makes easier to use pagination according
4
+ to the [JSON API](http://jsonapi.org/format/#fetching-pagination) conventions.
4
5
 
5
6
  Forked from: [https://github.com/bacarini/jbuilder_pagination](https://github.com/bacarini/jbuilder_pagination)
6
7
 
7
8
  ## Requirement
8
9
 
9
- `JbuilderPaginationPlus` relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
10
+ `JbuilderPaginationPlus` relies on a paginated collection with the methods `current_page`, `total_pages`,
11
+ and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari)
12
+ or [WillPaginate](https://github.com/mislav/will_paginate).
10
13
 
11
14
  ## Installation
12
15
 
@@ -79,13 +82,60 @@ end
79
82
  # }
80
83
  # }
81
84
  ```
82
- The options `url` and `query_parameters` are opcionals.
85
+ The options `url` and `query_parameters` are optional.
83
86
 
84
87
  In case there is no pagination at all, `links` will be omitted.
85
88
 
89
+ If you want to keep the original query parameters passed in you could do something this:
90
+
91
+ ```ruby
92
+ json.links do
93
+ json.pages! @posts, url: request.original_url, query_parameters: { images: params[:images] }
94
+ end
95
+
96
+ json.data do
97
+ # Whatever your data is
98
+ end
99
+ ```
100
+
101
+ jbuilder_pagination_plus will deep merge query parameters with the original request parameters.
102
+
103
+
104
+ If that's not what you need then you can get the url using rails helpers:
105
+
106
+ ```ruby
107
+ json.links do
108
+ json.pages! @posts, url: posts_url
109
+ end
110
+
111
+ json.data do
112
+ # Whatever your data is
113
+ end
114
+ ```
115
+
116
+ If you need pagination but don't want the performance penalty of counting all of the records, you can use
117
+ to generate links without generating a `last` url. This should be compatible with `Kaminari`'s
118
+ `without_count` scope which can be used to paginate without issuing a `COUNT(*)` query.
119
+
120
+ ```ruby
121
+ json.links do
122
+ json.pages_no_count! @posts, url: posts_url
123
+ end
124
+
125
+ json.data do
126
+ # Whatever your data is
127
+ end
128
+ ```
129
+
130
+ The `pages!` method will automatically switch to `no_count` mode if it detects that the collection
131
+ doesn't respond properly to a `total_pages` method call.
132
+
86
133
  ## Development
87
134
 
88
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
135
+ After checking out the repo, run `bin/setup` to install dependencies.
136
+ Then, run `bin/console` for an interactive prompt that will allow you to experiment.
137
+
138
+ To run tests, run `rake spec`
89
139
 
90
140
  ## Contributing
91
141
 
@@ -5,13 +5,13 @@ require 'jbuilder/pagination/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "jbuilder_pagination_plus"
8
- spec.version = Jbuilder::Pagination::VERSION
8
+ spec.version = Pagination::VERSION
9
9
  spec.authors = ["Bruno Bacarini", "Andrew Newell"]
10
10
  spec.email = ["bacarini.bruno@gmail.com", "scytherswings@gmail.com"]
11
11
 
12
12
  spec.summary = "Jbuilder extension to allows pagination according to JSON API format"
13
13
  spec.description = "Jbuilder extension to allows pagination according to JSON API format. See http://jsonapi.org for details on the format. Also provides methods for simpler pagination in controllers"
14
- spec.homepage = "https://github.com/PinsterTeam/jbuilder_pagination_plus"
14
+ spec.homepage = "https://github.com/IlluminusLimited/jbuilder_pagination_plus"
15
15
  spec.license = "MIT"
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -8,6 +8,20 @@ module Pagination
8
8
  DEFAULT_PAGINATION = [[:page, ->(params) { params.dig(:page, :number) }],
9
9
  [:per, ->(params) { params.dig(:page, :size) }]].freeze
10
10
 
11
+ NO_COUNT_PAGINATION = [[:page, ->(params) { params.dig(:page, :number) }],
12
+ [:per, ->(params) { params.dig(:page, :size) }],
13
+ [:without_count]].freeze
14
+
15
+ # @param pageable_resource [Object] resource to be paged
16
+ # @param methods [Array<Symbol, Lambda>] array of methods to call on the pageable_resource
17
+ # @param params [Object] params object from the controller
18
+ def paginate_no_count(pageable_resource, methods = NO_COUNT_PAGINATION.dup, params = self.params)
19
+ paginate(pageable_resource, methods, params)
20
+ end
21
+
22
+ # @param pageable_resource [Object] resource to be paged
23
+ # @param methods [Array<Symbol, Lambda>] array of methods to call on the pageable_resource
24
+ # @param params [Object] params object from the controller
11
25
  def paginate(pageable_resource, methods = DEFAULT_PAGINATION.dup, params = self.params)
12
26
  return pageable_resource if methods.blank?
13
27
  key_value_array = methods.pop
@@ -16,11 +30,15 @@ module Pagination
16
30
 
17
31
  private
18
32
 
19
- def build_pagination(key_value_array, pageable_resource, params)
20
- unless pageable_resource.respond_to?(key_value_array[0])
21
- raise Errors::UnpageableResourceError, "Resource does not respond to '#{key_value_array[0]}' method!"
22
- end
33
+ def build_pagination(key_value_array, pageable_resource, params)
34
+ unless pageable_resource.respond_to?(key_value_array[0])
35
+ raise Errors::UnpageableResourceError, "Resource does not respond to '#{key_value_array[0]}' method!"
36
+ end
23
37
 
24
- pageable_resource.public_send(key_value_array[0], key_value_array[1].call(params))
38
+ if key_value_array[1].nil?
39
+ return pageable_resource.public_send(key_value_array[0])
25
40
  end
41
+
42
+ pageable_resource.public_send(key_value_array[0], key_value_array[1].call(params))
43
+ end
26
44
  end
@@ -1,50 +1,126 @@
1
1
  class Jbuilder
2
2
  ONE_PAGE = 1
3
3
 
4
- def pages!(collection, options = {})
4
+ # Used to generate the pagination links for a collection
5
+ # @param collection [Object] the paginated collection
6
+ # @param opts [Hash] options to pass in
7
+ # @option opts [String] :url The url to use
8
+ # @option opts [Hash] :query_parameters Query parameters to automatically add to any generated urls
9
+ # @option opts [Boolean] :no_count This can be passed to force pagination without counting the total which is
10
+ # an alternative to calling #pages_no_count!
11
+ def pages!(collection, opts = {})
5
12
  return unless collection && is_paginated?(collection)
6
13
 
7
- options_url = options.fetch(:url, nil)
14
+ options_query_parameters, original_params, original_url = handle_url(opts)
15
+
16
+ if opts.fetch(:no_count, false)
17
+ pages_without_count(collection, options_query_parameters, original_params, original_url)
18
+ elsif is_countable?(collection)
19
+ pages_with_count(collection, options_query_parameters, original_params, original_url)
20
+ else
21
+ pages_without_count(collection, options_query_parameters, original_params, original_url)
22
+ end
23
+ end
24
+
25
+ # Used to generate the pagination links for a collection without requiring the total_count
26
+ # @param collection [Object] the paginated collection
27
+ # @param opts [Hash] options to pass in
28
+ # @option opts [String] :url for the url to use
29
+ # @option opts [Hash] :query_parameters to automatically add to any generated urls
30
+ def pages_no_count!(collection, opts = {})
31
+ return unless collection && is_paginated?(collection)
32
+
33
+ options_query_parameters, original_params, original_url = handle_url(opts)
34
+
35
+ pages_without_count(collection, options_query_parameters, original_params, original_url)
36
+ end
37
+
38
+ private
39
+
40
+ def handle_url(opts)
41
+ options_url = opts.fetch(:url, nil)
8
42
  original_url = nil
9
43
  original_params = {}
10
44
  if options_url
11
45
  original_url, original_params = options_url.split("?")
12
46
  original_params = ::Rack::Utils.parse_nested_query(original_params).deep_symbolize_keys
13
47
  end
14
- options_query_parameters = options.fetch(:query_parameters, {})
48
+ options_query_parameters = opts.fetch(:query_parameters, {})
49
+ [options_query_parameters, original_params, original_url]
50
+ end
15
51
 
52
+ def pages_with_count(collection, options_query_parameters, original_params, original_url)
16
53
  pages_from(collection).map do |key, value|
17
- params = query_parameters(options_query_parameters, original_params).deep_merge(page: { number: value, size: collection.size }).to_query
18
- _set_value key, "#{original_url}?#{params}"
54
+ build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
19
55
  end
20
56
  end
21
57
 
22
- private
23
58
 
24
- def pages_from(collection)
25
- {}.tap do |pages|
26
- pages[:self] = collection.current_page
27
- return pages if collection.total_pages <= ONE_PAGE
28
59
 
29
- unless collection.current_page == ONE_PAGE
30
- pages[:first] = ONE_PAGE
31
- pages[:prev] = collection.current_page - ONE_PAGE
32
- end
60
+ def pages_without_count(collection, options_query_parameters, original_params, original_url)
61
+ pages_without_count_from(collection).map do |key, value|
62
+ build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
63
+ end
64
+ end
65
+
66
+ def build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
67
+ params = query_parameters(options_query_parameters, original_params)
68
+ .deep_merge(page: { number: value, size: collection.size })
69
+ .to_query
70
+ _set_value key, "#{original_url}?#{params}"
71
+ end
72
+
73
+ def pages_from(collection)
74
+ {}.tap do |pages|
75
+ pages[:self] = collection.current_page
76
+ return pages if collection.total_pages <= ONE_PAGE
33
77
 
34
- unless collection.current_page == collection.total_pages
35
- pages[:next] = collection.current_page + ONE_PAGE
36
- pages[:last] = collection.total_pages
37
- end
78
+ unless collection.current_page == ONE_PAGE
79
+ pages[:first] = ONE_PAGE
80
+ pages[:prev] = collection.current_page - ONE_PAGE
38
81
  end
39
- end
40
82
 
41
- def query_parameters(query_parameters, original_parameters)
42
- @query_parameters ||= original_parameters.deep_merge(query_parameters || {}).compact
83
+ unless collection.current_page == collection.total_pages
84
+ pages[:next] = collection.current_page + ONE_PAGE
85
+ pages[:last] = collection.total_pages
86
+ end
43
87
  end
88
+ end
89
+
90
+ def pages_without_count_from(collection)
91
+ {}.tap do |pages|
92
+ pages[:self] = collection.current_page
93
+
94
+ unless collection.current_page == ONE_PAGE
95
+ pages[:first] = ONE_PAGE
96
+ pages[:prev] = collection.current_page - ONE_PAGE
97
+ end
44
98
 
45
- def is_paginated?(collection)
46
- collection.respond_to?(:current_page) &&
47
- collection.respond_to?(:total_pages) &&
48
- collection.respond_to?(:size)
99
+ if collection.respond_to?(:last_page?) && collection.last_page?
100
+ # Do nothing
101
+ return pages
102
+ else
103
+ pages[:next] = collection.current_page + ONE_PAGE
104
+ end
49
105
  end
106
+ end
107
+
108
+ def query_parameters(query_parameters, original_parameters)
109
+ @query_parameters ||= original_parameters.deep_merge(query_parameters || {}).compact
110
+ end
111
+
112
+ def is_paginated?(collection)
113
+ collection.respond_to?(:current_page) &&
114
+ collection.respond_to?(:total_pages) &&
115
+ collection.respond_to?(:size)
116
+ end
117
+
118
+ # Kaminari raises an exception if you call #total_count on a #without_count-ed collection
119
+ # Rescue can't be good for performance which is why you should use pages_no_count! if you know you will be
120
+ # dealing with non-counted collections
121
+ def is_countable?(collection)
122
+ collection.total_pages
123
+ rescue ::StandardError
124
+ false
125
+ end
50
126
  end
@@ -1,5 +1,3 @@
1
- module Jbuilder
2
- class Pagination
3
- VERSION = "1.0.0"
4
- end
1
+ module Pagination
2
+ VERSION = "1.1.0".freeze
5
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jbuilder_pagination_plus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Bacarini
@@ -9,88 +9,88 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-05-09 00:00:00.000000000 Z
12
+ date: 2020-09-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: 2.0.0
21
18
  - - "~>"
22
19
  - !ruby/object:Gem::Version
23
20
  version: '2.0'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.0
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- version: 2.0.0
31
28
  - - "~>"
32
29
  - !ruby/object:Gem::Version
33
30
  version: '2.0'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: jbuilder
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 2.8.0
41
38
  - - "~>"
42
39
  - !ruby/object:Gem::Version
43
40
  version: '2.8'
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.8.0
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: 2.8.0
51
48
  - - "~>"
52
49
  - !ruby/object:Gem::Version
53
50
  version: '2.8'
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 2.8.0
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rspec
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: 3.8.0
61
58
  - - "~>"
62
59
  - !ruby/object:Gem::Version
63
60
  version: '3.8'
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 3.8.0
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: 3.8.0
71
68
  - - "~>"
72
69
  - !ruby/object:Gem::Version
73
70
  version: '3.8'
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 3.8.0
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: rake
76
76
  requirement: !ruby/object:Gem::Requirement
77
77
  requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: 12.0.0
81
78
  - - "~>"
82
79
  - !ruby/object:Gem::Version
83
80
  version: '12.0'
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 12.0.0
84
84
  type: :development
85
85
  prerelease: false
86
86
  version_requirements: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: 12.0.0
91
88
  - - "~>"
92
89
  - !ruby/object:Gem::Version
93
90
  version: '12.0'
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: 12.0.0
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: pry
96
96
  requirement: !ruby/object:Gem::Requirement
@@ -132,7 +132,7 @@ files:
132
132
  - lib/jbuilder/pagination/exceptions/unpageable_resource_error.rb
133
133
  - lib/jbuilder/pagination/pages.rb
134
134
  - lib/jbuilder/pagination/version.rb
135
- homepage: https://github.com/PinsterTeam/jbuilder_pagination_plus
135
+ homepage: https://github.com/IlluminusLimited/jbuilder_pagination_plus
136
136
  licenses:
137
137
  - MIT
138
138
  metadata: {}
@@ -151,8 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  requirements: []
154
- rubyforge_project:
155
- rubygems_version: 2.7.8
154
+ rubygems_version: 3.1.2
156
155
  signing_key:
157
156
  specification_version: 4
158
157
  summary: Jbuilder extension to allows pagination according to JSON API format