jbuilder_pagination_plus 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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