jbuilder_pagination_plus 0.0.2 → 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
- SHA1:
3
- metadata.gz: 97ca43221a3f22c2b74158298688d92bd46340c9
4
- data.tar.gz: 20c8892e8c423755cfd7b3e5e27b812e50f6768b
2
+ SHA256:
3
+ metadata.gz: 1a546f0bae157155cea8dafe471cd6e7a44dff00cb9a5823f42b53ef2726974d
4
+ data.tar.gz: dab71bf293fd753e220181d22ab8b9794b45722f532609f55196b442923c1bd6
5
5
  SHA512:
6
- metadata.gz: f977ecf09a870ff5fe4abe3a89cb766b4994f98e1d90bea0d9dd4d2654c8166e8ce47b627499895abdd6978e76dc31a368eb6ff89e77eeac5fd5d381161734f0
7
- data.tar.gz: db68215e0b2c45e2324c66505cf7b38a184099d10cfd6301791b3a7da03bc865217cbb736020025778b0c357e5353bd50bad098e875c127684be1481fa931ee3
6
+ metadata.gz: cb029327b276555c9e1cb4b05fb7600203dcaa25e8a9e7ebf5b62e2cee523f93d5b967cb6e4c3867b4ff9a4de37d8ff5310f4955109a8ab7e500410329cee815
7
+ data.tar.gz: 3eb3fe3370f2980db1930c2b27c01d006611ef4b81e6c0496c66840c512f8431f820246cae2135c68ac66dd7592552630b075efdef1c5533d84a4f46422fa108
@@ -1 +1 @@
1
- ruby-2.4.3
1
+ ruby-2.7.1
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.4.2
3
+ - 2.7.1
4
+ sudo: false
4
5
  install: bin/setup
5
6
  script:
6
7
  - bundle exec rspec spec
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
 
@@ -26,6 +29,17 @@ Or install it yourself as:
26
29
 
27
30
  ## Usage
28
31
 
32
+ ### Controller Module
33
+
34
+ Import the `Pagination` module in your controller
35
+
36
+ ```ruby
37
+ class ApplicationController < ActionController::API
38
+ include Pagination
39
+ end
40
+
41
+ ```
42
+
29
43
  ###### Kaminari examples
30
44
  ```ruby
31
45
  #array
@@ -68,13 +82,60 @@ end
68
82
  # }
69
83
  # }
70
84
  ```
71
- The options `url` and `query_parameters` are opcionals.
85
+ The options `url` and `query_parameters` are optional.
72
86
 
73
87
  In case there is no pagination at all, `links` will be omitted.
74
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
+
75
133
  ## Development
76
134
 
77
- 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`
78
139
 
79
140
  ## Contributing
80
141
 
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+
9
+ task default: %i[spec]
@@ -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)/}) }
@@ -19,8 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_runtime_dependency 'jbuilder', '~> 2.2', '>= 2.2.0'
23
- spec.add_development_dependency 'rspec', '~> 3.2', '>= 3.2.0'
24
- spec.add_development_dependency 'rake', '~> 10.0'
22
+ spec.add_runtime_dependency 'rack', '~> 2.0', '>= 2.0.0'
23
+ spec.add_runtime_dependency 'jbuilder', '~> 2.8', '>= 2.8.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.8', '>= 3.8.0'
25
+ spec.add_development_dependency 'rake', '~> 12.0', '>= 12.0.0'
25
26
  spec.add_development_dependency 'pry', '~> 0'
26
27
  end
@@ -1,5 +1,6 @@
1
- require "jbuilder"
2
- require "jbuilder/pagination/pages"
1
+ require 'rack/utils'
2
+ require 'jbuilder'
3
+ require 'jbuilder/pagination/pages'
3
4
  require 'jbuilder/pagination/exceptions/unpageable_resource_error'
4
5
 
5
6
  module Pagination
@@ -7,6 +8,20 @@ module Pagination
7
8
  DEFAULT_PAGINATION = [[:page, ->(params) { params.dig(:page, :number) }],
8
9
  [:per, ->(params) { params.dig(:page, :size) }]].freeze
9
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
10
25
  def paginate(pageable_resource, methods = DEFAULT_PAGINATION.dup, params = self.params)
11
26
  return pageable_resource if methods.blank?
12
27
  key_value_array = methods.pop
@@ -15,11 +30,15 @@ module Pagination
15
30
 
16
31
  private
17
32
 
18
- def build_pagination(key_value_array, pageable_resource, params)
19
- unless pageable_resource.respond_to?(key_value_array[0])
20
- raise Errors::UnpageableResourceError, "Resource does not respond to '#{key_value_array[0]}' method!"
21
- 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
22
37
 
23
- 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])
24
40
  end
41
+
42
+ pageable_resource.public_send(key_value_array[0], key_value_array[1].call(params))
43
+ end
25
44
  end
@@ -1,25 +1,83 @@
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
- pages_from(collection).map do |key, value|
8
- params = query_parameters(options).merge(page: { number: value, size: collection.size }).to_query
9
- _set_value key, "#{options.fetch(:url, nil)}?#{params}"
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)
10
22
  end
11
23
  end
12
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
+
13
38
  private
14
39
 
40
+ def handle_url(opts)
41
+ options_url = opts.fetch(:url, nil)
42
+ original_url = nil
43
+ original_params = {}
44
+ if options_url
45
+ original_url, original_params = options_url.split("?")
46
+ original_params = ::Rack::Utils.parse_nested_query(original_params).deep_symbolize_keys
47
+ end
48
+ options_query_parameters = opts.fetch(:query_parameters, {})
49
+ [options_query_parameters, original_params, original_url]
50
+ end
51
+
52
+ def pages_with_count(collection, options_query_parameters, original_params, original_url)
53
+ pages_from(collection).map do |key, value|
54
+ build_jbuilder_value(collection, key, options_query_parameters, original_params, original_url, value)
55
+ end
56
+ end
57
+
58
+
59
+
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
+
15
73
  def pages_from(collection)
16
74
  {}.tap do |pages|
17
75
  pages[:self] = collection.current_page
18
- return pages if collection.total_pages == ONE_PAGE
76
+ return pages if collection.total_pages <= ONE_PAGE
19
77
 
20
78
  unless collection.current_page == ONE_PAGE
21
79
  pages[:first] = ONE_PAGE
22
- pages[:prev] = collection.current_page - ONE_PAGE
80
+ pages[:prev] = collection.current_page - ONE_PAGE
23
81
  end
24
82
 
25
83
  unless collection.current_page == collection.total_pages
@@ -29,8 +87,26 @@ class Jbuilder
29
87
  end
30
88
  end
31
89
 
32
- def query_parameters(options)
33
- @query_parameters ||= options.fetch(:query_parameters, {})
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
98
+
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
105
+ end
106
+ end
107
+
108
+ def query_parameters(query_parameters, original_parameters)
109
+ @query_parameters ||= original_parameters.deep_merge(query_parameters || {}).compact
34
110
  end
35
111
 
36
112
  def is_paginated?(collection)
@@ -38,4 +114,13 @@ class Jbuilder
38
114
  collection.respond_to?(:total_pages) &&
39
115
  collection.respond_to?(:size)
40
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
41
126
  end
@@ -1,5 +1,3 @@
1
- module Jbuilder
2
- class Pagination
3
- VERSION = "0.0.2"
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: 0.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Bacarini
@@ -9,62 +9,88 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-05-17 00:00:00.000000000 Z
12
+ date: 2020-09-01 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '2.0'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '2.0'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
14
34
  - !ruby/object:Gem::Dependency
15
35
  name: jbuilder
16
36
  requirement: !ruby/object:Gem::Requirement
17
37
  requirements:
18
38
  - - "~>"
19
39
  - !ruby/object:Gem::Version
20
- version: '2.2'
40
+ version: '2.8'
21
41
  - - ">="
22
42
  - !ruby/object:Gem::Version
23
- version: 2.2.0
43
+ version: 2.8.0
24
44
  type: :runtime
25
45
  prerelease: false
26
46
  version_requirements: !ruby/object:Gem::Requirement
27
47
  requirements:
28
48
  - - "~>"
29
49
  - !ruby/object:Gem::Version
30
- version: '2.2'
50
+ version: '2.8'
31
51
  - - ">="
32
52
  - !ruby/object:Gem::Version
33
- version: 2.2.0
53
+ version: 2.8.0
34
54
  - !ruby/object:Gem::Dependency
35
55
  name: rspec
36
56
  requirement: !ruby/object:Gem::Requirement
37
57
  requirements:
38
58
  - - "~>"
39
59
  - !ruby/object:Gem::Version
40
- version: '3.2'
60
+ version: '3.8'
41
61
  - - ">="
42
62
  - !ruby/object:Gem::Version
43
- version: 3.2.0
63
+ version: 3.8.0
44
64
  type: :development
45
65
  prerelease: false
46
66
  version_requirements: !ruby/object:Gem::Requirement
47
67
  requirements:
48
68
  - - "~>"
49
69
  - !ruby/object:Gem::Version
50
- version: '3.2'
70
+ version: '3.8'
51
71
  - - ">="
52
72
  - !ruby/object:Gem::Version
53
- version: 3.2.0
73
+ version: 3.8.0
54
74
  - !ruby/object:Gem::Dependency
55
75
  name: rake
56
76
  requirement: !ruby/object:Gem::Requirement
57
77
  requirements:
58
78
  - - "~>"
59
79
  - !ruby/object:Gem::Version
60
- version: '10.0'
80
+ version: '12.0'
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 12.0.0
61
84
  type: :development
62
85
  prerelease: false
63
86
  version_requirements: !ruby/object:Gem::Requirement
64
87
  requirements:
65
88
  - - "~>"
66
89
  - !ruby/object:Gem::Version
67
- version: '10.0'
90
+ version: '12.0'
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: 12.0.0
68
94
  - !ruby/object:Gem::Dependency
69
95
  name: pry
70
96
  requirement: !ruby/object:Gem::Requirement
@@ -106,7 +132,7 @@ files:
106
132
  - lib/jbuilder/pagination/exceptions/unpageable_resource_error.rb
107
133
  - lib/jbuilder/pagination/pages.rb
108
134
  - lib/jbuilder/pagination/version.rb
109
- homepage: https://github.com/PinsterTeam/jbuilder_pagination_plus
135
+ homepage: https://github.com/IlluminusLimited/jbuilder_pagination_plus
110
136
  licenses:
111
137
  - MIT
112
138
  metadata: {}
@@ -125,8 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
151
  - !ruby/object:Gem::Version
126
152
  version: '0'
127
153
  requirements: []
128
- rubyforge_project:
129
- rubygems_version: 2.6.14
154
+ rubygems_version: 3.1.2
130
155
  signing_key:
131
156
  specification_version: 4
132
157
  summary: Jbuilder extension to allows pagination according to JSON API format