jsonapi-query_builder 0.1.7 → 0.2.1
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 +4 -4
- data/.github/workflows/lint.yml +31 -0
- data/.github/workflows/spec.yml +23 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +20 -0
- data/Gemfile.lock +140 -0
- data/README.md +30 -1
- data/jsonapi-query_builder.gemspec +7 -2
- data/lefthook.yml +2 -2
- data/lib/jsonapi/query_builder/base_query.rb +2 -0
- data/lib/jsonapi/query_builder/errors/unpermitted_sort_parameters.rb +17 -0
- data/lib/jsonapi/query_builder/mixins/paginate.rb +15 -4
- data/lib/jsonapi/query_builder/mixins/sort.rb +3 -8
- data/lib/jsonapi/query_builder/paginator/base_paginator.rb +22 -0
- data/lib/jsonapi/query_builder/paginator/kaminari.rb +34 -0
- data/lib/jsonapi/query_builder/paginator/keyset.rb +64 -0
- data/lib/jsonapi/query_builder/paginator/pagy.rb +27 -0
- data/lib/jsonapi/query_builder/paginator.rb +4 -0
- data/lib/jsonapi/query_builder/version.rb +1 -1
- data/lib/jsonapi/query_builder.rb +0 -2
- metadata +85 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f47ebd86badc968ef8a79333f49ac496c067ad6a26c6563cca0257c1e8cdeba2
|
|
4
|
+
data.tar.gz: ff874753c9a7ba077bf7876a8a598dd01058a0e2f7a2a982dde2fc579342a5d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc7168dad1ea652617381662a8e75cadbb132addb9b78d6af052b15b590d3f031fa143a6508e6f2feb52f82ee9f333892551378fa5a969ac5232bb48ca8b0c8e
|
|
7
|
+
data.tar.gz: 6ead187ee07d7d9db557c2010b3d2c992c01d05c888ad6a777716380fa565fc9aff54fb39db54120131bbb544418f789f53cade618c55db86d2aec3d03c08a61
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
standardrb:
|
|
11
|
+
runs-on: ubuntu-18.04
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v2
|
|
15
|
+
- uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
bundler-cache: true
|
|
18
|
+
- name: standardrb
|
|
19
|
+
run: bundle exec standardrb
|
|
20
|
+
|
|
21
|
+
rubocop-rspec:
|
|
22
|
+
runs-on: ubuntu-18.04
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v2
|
|
26
|
+
- uses: ruby/setup-ruby@v1
|
|
27
|
+
with:
|
|
28
|
+
bundler-cache: true
|
|
29
|
+
|
|
30
|
+
- name: rubocop
|
|
31
|
+
run: bundle exec rubocop --only RSpec
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: spec
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
rake-spec:
|
|
11
|
+
runs-on: ubuntu-18.04
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
ruby: [2.5, 2.6, 2.7, 3.0]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v2
|
|
18
|
+
- uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
ruby-version: ${{ matrix.ruby }}
|
|
21
|
+
bundler-cache: true
|
|
22
|
+
- name: rake spec
|
|
23
|
+
run: bundle exec rake spec
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.2
|
data/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Change log
|
|
2
|
+
|
|
3
|
+
## 0.2.1 (2021-10-04)
|
|
4
|
+
|
|
5
|
+
- [#22](https://github.com/infinum/jsonapi-query_builder/pull/22): Bump allowed pagy version.
|
|
6
|
+
|
|
7
|
+
## 0.2.0 (2021-09-29)
|
|
8
|
+
Added support for Kaminari and Keyset pagination strategies in addition to Pagy.
|
|
9
|
+
|
|
10
|
+
- [#21](https://github.com/infinum/jsonapi-query_builder/pull/21): Extract paginators.
|
|
11
|
+
|
|
12
|
+
## 0.1.9 (2021-05-07)
|
|
13
|
+
|
|
14
|
+
- [#18](https://github.com/infinum/jsonapi-query_builder/pull/18): Remove Ruby `to` version.
|
|
15
|
+
- [#9](https://github.com/infinum/jsonapi-query_builder/pull/9): added github actions
|
|
16
|
+
|
|
17
|
+
## 0.1.8 (2021-01-25)
|
|
18
|
+
|
|
19
|
+
- [#8](https://github.com/infinum/jsonapi-query_builder/pull/8): add support for ruby 3.0
|
|
20
|
+
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
jsonapi-query_builder (0.2.1)
|
|
5
|
+
activerecord (>= 5)
|
|
6
|
+
pagy (>= 3.5)
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
actionview (6.1.4.1)
|
|
12
|
+
activesupport (= 6.1.4.1)
|
|
13
|
+
builder (~> 3.1)
|
|
14
|
+
erubi (~> 1.4)
|
|
15
|
+
rails-dom-testing (~> 2.0)
|
|
16
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
17
|
+
activemodel (6.1.4.1)
|
|
18
|
+
activesupport (= 6.1.4.1)
|
|
19
|
+
activerecord (6.1.4.1)
|
|
20
|
+
activemodel (= 6.1.4.1)
|
|
21
|
+
activesupport (= 6.1.4.1)
|
|
22
|
+
activesupport (6.1.4.1)
|
|
23
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
24
|
+
i18n (>= 1.6, < 2)
|
|
25
|
+
minitest (>= 5.1)
|
|
26
|
+
tzinfo (~> 2.0)
|
|
27
|
+
zeitwerk (~> 2.3)
|
|
28
|
+
ast (2.4.2)
|
|
29
|
+
builder (3.2.4)
|
|
30
|
+
bundler-audit (0.9.0.1)
|
|
31
|
+
bundler (>= 1.2.0, < 3)
|
|
32
|
+
thor (~> 1.0)
|
|
33
|
+
coderay (1.1.3)
|
|
34
|
+
concurrent-ruby (1.1.9)
|
|
35
|
+
crass (1.0.6)
|
|
36
|
+
diff-lcs (1.4.4)
|
|
37
|
+
erubi (1.10.0)
|
|
38
|
+
i18n (1.8.10)
|
|
39
|
+
concurrent-ruby (~> 1.0)
|
|
40
|
+
kaminari (1.2.1)
|
|
41
|
+
activesupport (>= 4.1.0)
|
|
42
|
+
kaminari-actionview (= 1.2.1)
|
|
43
|
+
kaminari-activerecord (= 1.2.1)
|
|
44
|
+
kaminari-core (= 1.2.1)
|
|
45
|
+
kaminari-actionview (1.2.1)
|
|
46
|
+
actionview
|
|
47
|
+
kaminari-core (= 1.2.1)
|
|
48
|
+
kaminari-activerecord (1.2.1)
|
|
49
|
+
activerecord
|
|
50
|
+
kaminari-core (= 1.2.1)
|
|
51
|
+
kaminari-core (1.2.1)
|
|
52
|
+
lefthook (0.7.6)
|
|
53
|
+
loofah (2.12.0)
|
|
54
|
+
crass (~> 1.0.2)
|
|
55
|
+
nokogiri (>= 1.5.9)
|
|
56
|
+
method_source (1.0.0)
|
|
57
|
+
mini_portile2 (2.6.1)
|
|
58
|
+
minitest (5.14.4)
|
|
59
|
+
nokogiri (1.12.5)
|
|
60
|
+
mini_portile2 (~> 2.6.1)
|
|
61
|
+
racc (~> 1.4)
|
|
62
|
+
pagy (3.11.0)
|
|
63
|
+
parallel (1.21.0)
|
|
64
|
+
parser (3.0.2.0)
|
|
65
|
+
ast (~> 2.4.1)
|
|
66
|
+
pry (0.14.1)
|
|
67
|
+
coderay (~> 1.1)
|
|
68
|
+
method_source (~> 1.0)
|
|
69
|
+
racc (1.5.2)
|
|
70
|
+
rails-dom-testing (2.0.3)
|
|
71
|
+
activesupport (>= 4.2.0)
|
|
72
|
+
nokogiri (>= 1.6)
|
|
73
|
+
rails-html-sanitizer (1.4.2)
|
|
74
|
+
loofah (~> 2.3)
|
|
75
|
+
rainbow (3.0.0)
|
|
76
|
+
rake (13.0.6)
|
|
77
|
+
regexp_parser (2.1.1)
|
|
78
|
+
rexml (3.2.5)
|
|
79
|
+
rspec (3.10.0)
|
|
80
|
+
rspec-core (~> 3.10.0)
|
|
81
|
+
rspec-expectations (~> 3.10.0)
|
|
82
|
+
rspec-mocks (~> 3.10.0)
|
|
83
|
+
rspec-core (3.10.1)
|
|
84
|
+
rspec-support (~> 3.10.0)
|
|
85
|
+
rspec-expectations (3.10.1)
|
|
86
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
87
|
+
rspec-support (~> 3.10.0)
|
|
88
|
+
rspec-mocks (3.10.2)
|
|
89
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
90
|
+
rspec-support (~> 3.10.0)
|
|
91
|
+
rspec-support (3.10.2)
|
|
92
|
+
rubocop (1.20.0)
|
|
93
|
+
parallel (~> 1.10)
|
|
94
|
+
parser (>= 3.0.0.0)
|
|
95
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
96
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
97
|
+
rexml
|
|
98
|
+
rubocop-ast (>= 1.9.1, < 2.0)
|
|
99
|
+
ruby-progressbar (~> 1.7)
|
|
100
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
101
|
+
rubocop-ast (1.12.0)
|
|
102
|
+
parser (>= 3.0.1.1)
|
|
103
|
+
rubocop-performance (1.11.5)
|
|
104
|
+
rubocop (>= 1.7.0, < 2.0)
|
|
105
|
+
rubocop-ast (>= 0.4.0)
|
|
106
|
+
rubocop-rspec (2.5.0)
|
|
107
|
+
rubocop (~> 1.19)
|
|
108
|
+
ruby-progressbar (1.11.0)
|
|
109
|
+
sqlite3 (1.4.2)
|
|
110
|
+
standard (1.3.0)
|
|
111
|
+
rubocop (= 1.20.0)
|
|
112
|
+
rubocop-performance (= 1.11.5)
|
|
113
|
+
standardrb (1.0.0)
|
|
114
|
+
standard
|
|
115
|
+
thor (1.1.0)
|
|
116
|
+
tzinfo (2.0.4)
|
|
117
|
+
concurrent-ruby (~> 1.0)
|
|
118
|
+
unicode-display_width (2.1.0)
|
|
119
|
+
zeitwerk (2.4.2)
|
|
120
|
+
|
|
121
|
+
PLATFORMS
|
|
122
|
+
ruby
|
|
123
|
+
|
|
124
|
+
DEPENDENCIES
|
|
125
|
+
activerecord
|
|
126
|
+
bundler (~> 2.0)
|
|
127
|
+
bundler-audit
|
|
128
|
+
jsonapi-query_builder!
|
|
129
|
+
kaminari (~> 1.2)
|
|
130
|
+
lefthook
|
|
131
|
+
pry
|
|
132
|
+
rake (~> 13.0)
|
|
133
|
+
rspec (~> 3.0)
|
|
134
|
+
rubocop-rspec
|
|
135
|
+
sqlite3
|
|
136
|
+
standard
|
|
137
|
+
standardrb
|
|
138
|
+
|
|
139
|
+
BUNDLED WITH
|
|
140
|
+
2.2.22
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Jsonapi::QueryBuilder
|
|
1
|
+
# Jsonapi::QueryBuilder 
|
|
2
2
|
|
|
3
3
|
`Jsonapi::QueryBuilder` serves the purpose of adding the json api query related SQL conditions to the already scoped
|
|
4
4
|
collection, usually used in controller index actions.
|
|
@@ -27,6 +27,9 @@ Or install it yourself as:
|
|
|
27
27
|
|
|
28
28
|
```ruby
|
|
29
29
|
class UserQuery < Jsonapi::QueryBuilder::BaseQuery
|
|
30
|
+
## pagination
|
|
31
|
+
paginator Jsonapi::QueryBuilder::Paginator::Pagy # default paginator
|
|
32
|
+
|
|
30
33
|
## sorting
|
|
31
34
|
default_sort created_at: :desc
|
|
32
35
|
sorts_by :last_name
|
|
@@ -56,6 +59,29 @@ current user permissions, or for any other type of scoping. It's only responsibi
|
|
|
56
59
|
querying. Use `pundit` or similar for policy scoping, custom query objects for other scoping, and then pass the scoped
|
|
57
60
|
collection to the `Jsonapi::QueryBuilder::BaseQuery` object.
|
|
58
61
|
|
|
62
|
+
### Pagination
|
|
63
|
+
Pagination support is configurable using the `paginator` method to define the paginator. It defaults to the `Pagy`
|
|
64
|
+
paginator, a lightweight and fast paginator. Other paginators currently supported are `Kaminari` and an implementation
|
|
65
|
+
of keyset pagination. Before using these paginators we need to explicitly require the gems in our Gemfile and the
|
|
66
|
+
paginator file in question.
|
|
67
|
+
Additionally one can implement it's own paginator by inheriting from `Jsonapi::QueryBuilder::Paginator::BasePaginator`.
|
|
68
|
+
The minimum required implementation is a `#paginate` method that receives page params and returns a page of the
|
|
69
|
+
collection. It can return the pagination details as the second item of the returned array, that can be used in the
|
|
70
|
+
serializer for pagination metadata.
|
|
71
|
+
#### Using the Kaminari Paginator
|
|
72
|
+
```ruby
|
|
73
|
+
require "jsonapi/query_builder/paginator/kaminari"
|
|
74
|
+
|
|
75
|
+
paginator Jsonapi::QueryBuilder::Paginator::Kaminari
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Using the Keyset Paginator
|
|
79
|
+
```ruby
|
|
80
|
+
require "jsonapi/query_builder/paginator/keyset"
|
|
81
|
+
|
|
82
|
+
paginator Jsonapi::QueryBuilder::Paginator::Keyset
|
|
83
|
+
```
|
|
84
|
+
|
|
59
85
|
### Sorting
|
|
60
86
|
#### Ensuring deterministic results
|
|
61
87
|
Sorting has a fallback to an unique attribute which defaults to the `id` attribute. This ensures deterministic paginated
|
|
@@ -165,6 +191,9 @@ filters_by :type, TypeFilter, if: :correct_type?
|
|
|
165
191
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
|
|
166
192
|
also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
167
193
|
|
|
194
|
+
We're using `standardrb` and `lefthook`. You can install lefthook hooks via `lefthook install`. It will run linters and
|
|
195
|
+
standardrb checks before commits, and a bundle audit + whole spec suite before push.
|
|
196
|
+
|
|
168
197
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
|
169
198
|
version number in `version.rb`, and then run `LEFTHOOK=0 bundle exec rake release`, which will create a git tag for the
|
|
170
199
|
version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
@@ -36,16 +36,21 @@ Gem::Specification.new do |spec|
|
|
|
36
36
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
37
37
|
spec.require_paths = ["lib"]
|
|
38
38
|
|
|
39
|
-
spec.required_ruby_version = "
|
|
39
|
+
spec.required_ruby_version = ">= 2.5"
|
|
40
40
|
|
|
41
41
|
spec.add_runtime_dependency "activerecord", ">= 5"
|
|
42
|
-
spec.add_runtime_dependency "pagy", "
|
|
42
|
+
spec.add_runtime_dependency "pagy", ">= 3.5"
|
|
43
43
|
|
|
44
44
|
spec.add_development_dependency "bundler", "~> 2.0"
|
|
45
|
+
spec.add_development_dependency "bundler-audit"
|
|
45
46
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
46
47
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
47
48
|
spec.add_development_dependency "standardrb"
|
|
48
49
|
spec.add_development_dependency "standard"
|
|
49
50
|
spec.add_development_dependency "rubocop-rspec"
|
|
50
51
|
spec.add_development_dependency "lefthook"
|
|
52
|
+
spec.add_development_dependency "kaminari", "~> 1.2"
|
|
53
|
+
spec.add_development_dependency "activerecord"
|
|
54
|
+
spec.add_development_dependency "sqlite3"
|
|
55
|
+
spec.add_development_dependency "pry"
|
|
51
56
|
end
|
data/lefthook.yml
CHANGED
|
@@ -2,13 +2,13 @@ lint:
|
|
|
2
2
|
commands: &lint
|
|
3
3
|
lint-frozen-strings:
|
|
4
4
|
glob: "*.rb"
|
|
5
|
-
run: bundle exec rubocop
|
|
5
|
+
run: bundle exec rubocop --only Style/FrozenStringLiteralComment,Layout/EmptyLineAfterMagicComment --format quiet --auto-correct
|
|
6
6
|
|
|
7
7
|
rubocop:
|
|
8
8
|
commands: &rubocop
|
|
9
9
|
rubocop-rspec:
|
|
10
10
|
glob: "spec/*"
|
|
11
|
-
run: bundle exec rubocop
|
|
11
|
+
run: bundle exec rubocop --only RSpec --format quiet
|
|
12
12
|
|
|
13
13
|
pre-commit:
|
|
14
14
|
parallel: true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsonapi
|
|
4
|
+
module QueryBuilder
|
|
5
|
+
module Errors
|
|
6
|
+
class UnpermittedSortParameters < ArgumentError
|
|
7
|
+
def initialize(unpermitted_parameters)
|
|
8
|
+
super [
|
|
9
|
+
unpermitted_parameters.to_sentence,
|
|
10
|
+
unpermitted_parameters.count == 1 ? "is not a" : "are not",
|
|
11
|
+
"permitted sort attribute".pluralize(unpermitted_parameters.count)
|
|
12
|
+
].join(" ")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -4,7 +4,20 @@ module Jsonapi
|
|
|
4
4
|
module QueryBuilder
|
|
5
5
|
module Mixins
|
|
6
6
|
module Paginate
|
|
7
|
-
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
class_methods do
|
|
10
|
+
# Sets the paginator used to page the results. Defaults to Pagy
|
|
11
|
+
#
|
|
12
|
+
# @param [Jsonapi::QueryBuilder::Paginator::BasePaginator] paginator A subclass of BasePaginator
|
|
13
|
+
def paginator(paginator)
|
|
14
|
+
@paginator = paginator
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def _paginator
|
|
18
|
+
@paginator || Paginator::Pagy
|
|
19
|
+
end
|
|
20
|
+
end
|
|
8
21
|
|
|
9
22
|
attr_reader :pagination_details
|
|
10
23
|
|
|
@@ -14,9 +27,7 @@ module Jsonapi
|
|
|
14
27
|
# @param [Object] page_params Optional explicit pagination params
|
|
15
28
|
# @return [ActiveRecord::Relation] Paged collection
|
|
16
29
|
def paginate(collection, page_params = send(:page_params))
|
|
17
|
-
@pagination_details
|
|
18
|
-
items: page_params[:size],
|
|
19
|
-
outset: page_params[:offset]
|
|
30
|
+
records, @pagination_details = self.class._paginator.new(collection).paginate(page_params)
|
|
20
31
|
|
|
21
32
|
records
|
|
22
33
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "jsonapi/query_builder/mixins/sort/param"
|
|
4
|
+
require "jsonapi/query_builder/errors/unpermitted_sort_parameters"
|
|
4
5
|
|
|
5
6
|
module Jsonapi
|
|
6
7
|
module QueryBuilder
|
|
@@ -8,8 +9,6 @@ module Jsonapi
|
|
|
8
9
|
module Sort
|
|
9
10
|
extend ActiveSupport::Concern
|
|
10
11
|
|
|
11
|
-
UnpermittedSortParameters = Class.new ArgumentError
|
|
12
|
-
|
|
13
12
|
class_methods do
|
|
14
13
|
attr_reader :_default_sort
|
|
15
14
|
|
|
@@ -59,7 +58,7 @@ module Jsonapi
|
|
|
59
58
|
# @param [ActiveRecord::Relation] collection
|
|
60
59
|
# @param [Object] sort_params Optional explicit sort params
|
|
61
60
|
# @return [ActiveRecord::Relation] Sorted relation
|
|
62
|
-
# @raise [Jsonapi::QueryBuilder::
|
|
61
|
+
# @raise [Jsonapi::QueryBuilder::Errors::UnpermittedSortParameters] if not all sort parameters are
|
|
63
62
|
# permitted
|
|
64
63
|
def sort(collection, sort_params = send(:sort_params))
|
|
65
64
|
sort_params = Param.deserialize_params(sort_params)
|
|
@@ -80,11 +79,7 @@ module Jsonapi
|
|
|
80
79
|
unpermitted_parameters = sort_params.map(&:attribute).map(&:to_sym) - self.class.supported_sorts.keys
|
|
81
80
|
return if unpermitted_parameters.size.zero?
|
|
82
81
|
|
|
83
|
-
raise UnpermittedSortParameters,
|
|
84
|
-
unpermitted_parameters.to_sentence,
|
|
85
|
-
unpermitted_parameters.count == 1 ? "is not a" : "are not",
|
|
86
|
-
"permitted sort attribute".pluralize(unpermitted_parameters.count)
|
|
87
|
-
].join(" ")
|
|
82
|
+
raise Errors::UnpermittedSortParameters, unpermitted_parameters
|
|
88
83
|
end
|
|
89
84
|
|
|
90
85
|
def add_order_attributes(collection, sort_params)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsonapi
|
|
4
|
+
module QueryBuilder
|
|
5
|
+
module Paginator
|
|
6
|
+
class BasePaginator
|
|
7
|
+
attr_reader :collection
|
|
8
|
+
|
|
9
|
+
# @param [ActiveRecord::Relation] collection
|
|
10
|
+
def initialize(collection)
|
|
11
|
+
@collection = collection
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @param [Hash] page_params
|
|
15
|
+
# @return [[ActiveRecord::Relation, Hash]] Records and pagination details
|
|
16
|
+
def paginate(page_params)
|
|
17
|
+
raise NotImplementedError, "#{self.class} should implement ##{__method__}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "kaminari"
|
|
4
|
+
|
|
5
|
+
module Jsonapi
|
|
6
|
+
module QueryBuilder
|
|
7
|
+
module Paginator
|
|
8
|
+
class Kaminari < BasePaginator
|
|
9
|
+
def paginate(page_params)
|
|
10
|
+
paged_collection = collection
|
|
11
|
+
.page(page_params[:number])
|
|
12
|
+
.per(page_params[:size])
|
|
13
|
+
.padding(page_params[:offset])
|
|
14
|
+
|
|
15
|
+
[paged_collection, pagination_details(paged_collection, page_params)]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def pagination_details(collection, page_params)
|
|
21
|
+
{
|
|
22
|
+
number: collection.current_page,
|
|
23
|
+
size: collection.limit_value,
|
|
24
|
+
offset: page_params[:offset],
|
|
25
|
+
total: collection.total_count,
|
|
26
|
+
total_pages: collection.total_pages,
|
|
27
|
+
next_page: collection.next_page,
|
|
28
|
+
prev_page: collection.prev_page
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_record"
|
|
4
|
+
|
|
5
|
+
module Jsonapi
|
|
6
|
+
module QueryBuilder
|
|
7
|
+
module Paginator
|
|
8
|
+
class Keyset < BasePaginator
|
|
9
|
+
DEFAULT_DIRECTION = :after
|
|
10
|
+
DEFAULT_LIMIT = 25
|
|
11
|
+
|
|
12
|
+
def paginate(page_params)
|
|
13
|
+
page_params = extract_pagination_params(page_params)
|
|
14
|
+
records = apply_pagination(collection, page_params)
|
|
15
|
+
|
|
16
|
+
[records, page_params]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def extract_pagination_params(params)
|
|
22
|
+
{
|
|
23
|
+
column: params.fetch(:column, nil),
|
|
24
|
+
position: params.fetch(:position, nil),
|
|
25
|
+
direction: params.fetch(:direction, DEFAULT_DIRECTION),
|
|
26
|
+
limit: params.fetch(:limit, DEFAULT_LIMIT)
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def apply_pagination(collection, pagination_params)
|
|
31
|
+
column = pagination_params[:column]
|
|
32
|
+
position = pagination_params[:position]
|
|
33
|
+
direction = pagination_params[:direction]
|
|
34
|
+
limit = pagination_params[:limit]
|
|
35
|
+
|
|
36
|
+
return collection unless column
|
|
37
|
+
|
|
38
|
+
collection = apply_order(collection, column, direction)
|
|
39
|
+
collection = collection.limit(limit.to_i)
|
|
40
|
+
|
|
41
|
+
return collection unless position
|
|
42
|
+
|
|
43
|
+
apply_filter(collection, column, position, direction)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def apply_order(collection, column, direction)
|
|
47
|
+
if direction.to_sym == DEFAULT_DIRECTION
|
|
48
|
+
collection.reorder(collection.arel_table[column].asc)
|
|
49
|
+
else
|
|
50
|
+
collection.reorder(collection.arel_table[column].desc)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def apply_filter(collection, column, position, direction)
|
|
55
|
+
if direction.to_sym == DEFAULT_DIRECTION
|
|
56
|
+
collection.where(collection.arel_table[column].gt(position))
|
|
57
|
+
else
|
|
58
|
+
collection.where(collection.arel_table[column].lt(position))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pagy"
|
|
4
|
+
require "pagy/extras/items"
|
|
5
|
+
|
|
6
|
+
module Jsonapi
|
|
7
|
+
module QueryBuilder
|
|
8
|
+
module Paginator
|
|
9
|
+
class Pagy < BasePaginator
|
|
10
|
+
include ::Pagy::Backend
|
|
11
|
+
|
|
12
|
+
def paginate(page_params)
|
|
13
|
+
@params = {page: page_params}
|
|
14
|
+
|
|
15
|
+
pagination_details, records = pagy collection, page: page_params[:number],
|
|
16
|
+
items: page_params[:size],
|
|
17
|
+
outset: page_params[:offset]
|
|
18
|
+
[records, pagination_details]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
attr_reader :params
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -4,8 +4,6 @@ require "active_support/concern"
|
|
|
4
4
|
require "active_support/core_ext/array/conversions"
|
|
5
5
|
require "active_support/core_ext/hash/keys"
|
|
6
6
|
require "active_support/core_ext/string/inflections"
|
|
7
|
-
require "pagy"
|
|
8
|
-
require "pagy/extras/items"
|
|
9
7
|
|
|
10
8
|
require "jsonapi/query_builder/version"
|
|
11
9
|
require "jsonapi/query_builder/base_query"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jsonapi-query_builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jure Cindro
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -28,14 +28,14 @@ dependencies:
|
|
|
28
28
|
name: pagy
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '3.5'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '3.5'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '2.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler-audit
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: rake
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,6 +150,62 @@ dependencies:
|
|
|
136
150
|
- - ">="
|
|
137
151
|
- !ruby/object:Gem::Version
|
|
138
152
|
version: '0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: kaminari
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '1.2'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '1.2'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: activerecord
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '0'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: sqlite3
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '0'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0'
|
|
195
|
+
- !ruby/object:Gem::Dependency
|
|
196
|
+
name: pry
|
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
|
198
|
+
requirements:
|
|
199
|
+
- - ">="
|
|
200
|
+
- !ruby/object:Gem::Version
|
|
201
|
+
version: '0'
|
|
202
|
+
type: :development
|
|
203
|
+
prerelease: false
|
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - ">="
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: '0'
|
|
139
209
|
description: |
|
|
140
210
|
`Jsonapi::QueryBuilder` serves the purpose of adding the json api query related SQL conditions to the already scoped collection, usually used in controller index actions.
|
|
141
211
|
|
|
@@ -146,12 +216,15 @@ executables: []
|
|
|
146
216
|
extensions: []
|
|
147
217
|
extra_rdoc_files: []
|
|
148
218
|
files:
|
|
219
|
+
- ".github/workflows/lint.yml"
|
|
220
|
+
- ".github/workflows/spec.yml"
|
|
149
221
|
- ".gitignore"
|
|
150
222
|
- ".rspec"
|
|
151
223
|
- ".rubocop.yml"
|
|
152
224
|
- ".ruby-version"
|
|
153
225
|
- CHANGELOG.md
|
|
154
226
|
- Gemfile
|
|
227
|
+
- Gemfile.lock
|
|
155
228
|
- LICENSE.txt
|
|
156
229
|
- README.md
|
|
157
230
|
- Rakefile
|
|
@@ -163,11 +236,17 @@ files:
|
|
|
163
236
|
- lib/jsonapi/query_builder/base_filter.rb
|
|
164
237
|
- lib/jsonapi/query_builder/base_query.rb
|
|
165
238
|
- lib/jsonapi/query_builder/base_sort.rb
|
|
239
|
+
- lib/jsonapi/query_builder/errors/unpermitted_sort_parameters.rb
|
|
166
240
|
- lib/jsonapi/query_builder/mixins/filter.rb
|
|
167
241
|
- lib/jsonapi/query_builder/mixins/include.rb
|
|
168
242
|
- lib/jsonapi/query_builder/mixins/paginate.rb
|
|
169
243
|
- lib/jsonapi/query_builder/mixins/sort.rb
|
|
170
244
|
- lib/jsonapi/query_builder/mixins/sort/param.rb
|
|
245
|
+
- lib/jsonapi/query_builder/paginator.rb
|
|
246
|
+
- lib/jsonapi/query_builder/paginator/base_paginator.rb
|
|
247
|
+
- lib/jsonapi/query_builder/paginator/kaminari.rb
|
|
248
|
+
- lib/jsonapi/query_builder/paginator/keyset.rb
|
|
249
|
+
- lib/jsonapi/query_builder/paginator/pagy.rb
|
|
171
250
|
- lib/jsonapi/query_builder/version.rb
|
|
172
251
|
homepage: https://github.com/infinum/jsonapi-query_builder
|
|
173
252
|
licenses:
|
|
@@ -182,7 +261,7 @@ require_paths:
|
|
|
182
261
|
- lib
|
|
183
262
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
184
263
|
requirements:
|
|
185
|
-
- - "
|
|
264
|
+
- - ">="
|
|
186
265
|
- !ruby/object:Gem::Version
|
|
187
266
|
version: '2.5'
|
|
188
267
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
@@ -191,7 +270,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
191
270
|
- !ruby/object:Gem::Version
|
|
192
271
|
version: '0'
|
|
193
272
|
requirements: []
|
|
194
|
-
rubygems_version: 3.
|
|
273
|
+
rubygems_version: 3.2.22
|
|
195
274
|
signing_key:
|
|
196
275
|
specification_version: 4
|
|
197
276
|
summary: Support `json:api` querying with ease!
|