jbuilder_pagination_plus 0.0.2 → 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
- 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