jsonapi-query_builder 0.1.8 → 0.3.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 +4 -4
- data/.github/workflows/lint.yml +31 -0
- data/.github/workflows/spec.yml +23 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +30 -0
- data/Gemfile.lock +85 -37
- data/README.md +78 -13
- 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/base_sort.rb +1 -1
- 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 +16 -9
- 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 +83 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c0bbac3427e5cd55ee1f3528925a7d5f06817bef89e232a668821450a8cbedf0
|
|
4
|
+
data.tar.gz: 622b993193db4a2644187a99099ed5470380dae1d4f576efccf0465d84a8e7f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5719e6ab6411803bd98cc6aa06ce8471a19c90f713c4b1c014106338bde1b7d7495bcac4be216349524c92489d5873327ba31cc7d4e99c075249ce6db149a54f
|
|
7
|
+
data.tar.gz: 6151a1cd285f11ed2f48c7c140442a3f67ba85f656d601d8a5ad4c2c686c973aad0526340a37271194e9400642db951d071d43993f7d37095fc47861ae89daf0
|
|
@@ -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/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
+
## 0.3.0 (2021-12-07)
|
|
4
|
+
|
|
5
|
+
### Enhancements
|
|
6
|
+
|
|
7
|
+
- Add support for proc and object default
|
|
8
|
+
sorts [a167f90](https://github.com/infinum/jsonapi-query_builder/commit/a167f90ca718fe62c0899520cd4c5c859f89035b)
|
|
9
|
+
|
|
10
|
+
## 0.2.1 (2021-10-04)
|
|
11
|
+
|
|
12
|
+
### Bugfixes
|
|
13
|
+
|
|
14
|
+
- [#22](https://github.com/infinum/jsonapi-query_builder/pull/22): Bump allowed pagy version.
|
|
15
|
+
|
|
16
|
+
## 0.2.0 (2021-09-29)
|
|
17
|
+
|
|
18
|
+
### Enhancements
|
|
19
|
+
|
|
20
|
+
Added support for Kaminari and Keyset pagination strategies in addition to Pagy.
|
|
21
|
+
|
|
22
|
+
- [#21](https://github.com/infinum/jsonapi-query_builder/pull/21): Extract paginators.
|
|
23
|
+
|
|
24
|
+
## 0.1.9 (2021-05-07)
|
|
25
|
+
|
|
26
|
+
### Enhancements
|
|
27
|
+
|
|
28
|
+
- [#18](https://github.com/infinum/jsonapi-query_builder/pull/18): Remove Ruby `to` version.
|
|
29
|
+
- [#9](https://github.com/infinum/jsonapi-query_builder/pull/9): added github actions
|
|
30
|
+
|
|
3
31
|
## 0.1.8 (2021-01-25)
|
|
4
32
|
|
|
33
|
+
### Enhancements
|
|
34
|
+
|
|
5
35
|
- [#8](https://github.com/infinum/jsonapi-query_builder/pull/8): add support for ruby 3.0
|
|
6
36
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,39 +1,81 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
jsonapi-query_builder (0.
|
|
4
|
+
jsonapi-query_builder (0.3.0)
|
|
5
5
|
activerecord (>= 5)
|
|
6
|
-
pagy (
|
|
6
|
+
pagy (>= 3.5)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
|
|
12
|
-
activesupport (= 6.1.1)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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)
|
|
17
23
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
18
24
|
i18n (>= 1.6, < 2)
|
|
19
25
|
minitest (>= 5.1)
|
|
20
26
|
tzinfo (~> 2.0)
|
|
21
27
|
zeitwerk (~> 2.3)
|
|
22
|
-
ast (2.4.
|
|
23
|
-
|
|
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)
|
|
24
36
|
diff-lcs (1.4.4)
|
|
25
|
-
|
|
37
|
+
erubi (1.10.0)
|
|
38
|
+
i18n (1.8.10)
|
|
26
39
|
concurrent-ruby (~> 1.0)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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)
|
|
32
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)
|
|
33
75
|
rainbow (3.0.0)
|
|
34
|
-
rake (13.0.
|
|
35
|
-
regexp_parser (2.
|
|
36
|
-
rexml (3.2.
|
|
76
|
+
rake (13.0.6)
|
|
77
|
+
regexp_parser (2.1.1)
|
|
78
|
+
rexml (3.2.5)
|
|
37
79
|
rspec (3.10.0)
|
|
38
80
|
rspec-core (~> 3.10.0)
|
|
39
81
|
rspec-expectations (~> 3.10.0)
|
|
@@ -43,50 +85,56 @@ GEM
|
|
|
43
85
|
rspec-expectations (3.10.1)
|
|
44
86
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
45
87
|
rspec-support (~> 3.10.0)
|
|
46
|
-
rspec-mocks (3.10.
|
|
88
|
+
rspec-mocks (3.10.2)
|
|
47
89
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
48
90
|
rspec-support (~> 3.10.0)
|
|
49
|
-
rspec-support (3.10.
|
|
50
|
-
rubocop (1.
|
|
91
|
+
rspec-support (3.10.2)
|
|
92
|
+
rubocop (1.20.0)
|
|
51
93
|
parallel (~> 1.10)
|
|
52
|
-
parser (>=
|
|
94
|
+
parser (>= 3.0.0.0)
|
|
53
95
|
rainbow (>= 2.2.2, < 4.0)
|
|
54
96
|
regexp_parser (>= 1.8, < 3.0)
|
|
55
97
|
rexml
|
|
56
|
-
rubocop-ast (>= 1.
|
|
98
|
+
rubocop-ast (>= 1.9.1, < 2.0)
|
|
57
99
|
ruby-progressbar (~> 1.7)
|
|
58
|
-
unicode-display_width (>= 1.4.0, <
|
|
59
|
-
rubocop-ast (1.
|
|
60
|
-
parser (>=
|
|
61
|
-
rubocop-performance (1.
|
|
62
|
-
rubocop (>=
|
|
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)
|
|
63
105
|
rubocop-ast (>= 0.4.0)
|
|
64
|
-
rubocop-rspec (2.
|
|
65
|
-
rubocop (~> 1.
|
|
66
|
-
rubocop-ast (>= 1.1.0)
|
|
106
|
+
rubocop-rspec (2.5.0)
|
|
107
|
+
rubocop (~> 1.19)
|
|
67
108
|
ruby-progressbar (1.11.0)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
rubocop
|
|
109
|
+
sqlite3 (1.4.2)
|
|
110
|
+
standard (1.3.0)
|
|
111
|
+
rubocop (= 1.20.0)
|
|
112
|
+
rubocop-performance (= 1.11.5)
|
|
71
113
|
standardrb (1.0.0)
|
|
72
114
|
standard
|
|
115
|
+
thor (1.1.0)
|
|
73
116
|
tzinfo (2.0.4)
|
|
74
117
|
concurrent-ruby (~> 1.0)
|
|
75
|
-
unicode-display_width (1.
|
|
118
|
+
unicode-display_width (2.1.0)
|
|
76
119
|
zeitwerk (2.4.2)
|
|
77
120
|
|
|
78
121
|
PLATFORMS
|
|
79
122
|
ruby
|
|
80
123
|
|
|
81
124
|
DEPENDENCIES
|
|
125
|
+
activerecord
|
|
82
126
|
bundler (~> 2.0)
|
|
127
|
+
bundler-audit
|
|
83
128
|
jsonapi-query_builder!
|
|
129
|
+
kaminari (~> 1.2)
|
|
84
130
|
lefthook
|
|
131
|
+
pry
|
|
85
132
|
rake (~> 13.0)
|
|
86
133
|
rspec (~> 3.0)
|
|
87
134
|
rubocop-rspec
|
|
135
|
+
sqlite3
|
|
88
136
|
standard
|
|
89
137
|
standardrb
|
|
90
138
|
|
|
91
139
|
BUNDLED WITH
|
|
92
|
-
2.
|
|
140
|
+
2.2.22
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
|
-
collection, usually used in controller index actions.
|
|
4
|
+
collection, usually used in controller index actions.
|
|
5
5
|
|
|
6
6
|
With the query builder we can easily define logic for query filters, attributes by which we can sort, and delegate
|
|
7
7
|
pagination parameters to the underlying paginator. Included relationships are automatically included via the
|
|
@@ -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
|
|
@@ -51,63 +54,112 @@ end
|
|
|
51
54
|
```
|
|
52
55
|
|
|
53
56
|
The query class is initialized using a collection and query parameters. Since query parameters are referenced explicitly
|
|
54
|
-
we can pass them as an unsafe hash. `Jsonapi::QueryBuilder::BaseQuery` should not be responsible for scoping records
|
|
55
|
-
current user permissions, or for any other type of scoping. It's only responsibility is to support
|
|
56
|
-
querying. Use `pundit` or similar for policy scoping, custom query objects for other scoping, and then
|
|
57
|
-
collection to the `Jsonapi::QueryBuilder::BaseQuery` object.
|
|
57
|
+
we can pass them as an unsafe hash. `Jsonapi::QueryBuilder::BaseQuery` should not be responsible for scoping records
|
|
58
|
+
based on current user permissions, or for any other type of scoping. It's only responsibility is to support
|
|
59
|
+
the `json:api` querying. Use `pundit` or similar for policy scoping, custom query objects for other scoping, and then
|
|
60
|
+
pass the scoped collection to the `Jsonapi::QueryBuilder::BaseQuery` object.
|
|
61
|
+
|
|
62
|
+
### Pagination
|
|
63
|
+
|
|
64
|
+
Pagination support is configurable using the `paginator` method to define the paginator. It defaults to the `Pagy`
|
|
65
|
+
paginator, a lightweight and fast paginator. Other paginators currently supported are `Kaminari` and an implementation
|
|
66
|
+
of keyset pagination. Before using these paginators we need to explicitly require the gems in our Gemfile and the
|
|
67
|
+
paginator file in question. Additionally one can implement it's own paginator by inheriting
|
|
68
|
+
from `Jsonapi::QueryBuilder::Paginator::BasePaginator`. The minimum required implementation is a `#paginate` method that
|
|
69
|
+
receives page params and returns a page of the collection. It can return the pagination details as the second item of
|
|
70
|
+
the returned array, that can be used in the serializer for pagination metadata.
|
|
71
|
+
|
|
72
|
+
#### Using the Kaminari Paginator
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
require "jsonapi/query_builder/paginator/kaminari"
|
|
76
|
+
|
|
77
|
+
paginator Jsonapi::QueryBuilder::Paginator::Kaminari
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### Using the Keyset Paginator
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
require "jsonapi/query_builder/paginator/keyset"
|
|
84
|
+
|
|
85
|
+
paginator Jsonapi::QueryBuilder::Paginator::Keyset
|
|
86
|
+
```
|
|
58
87
|
|
|
59
88
|
### Sorting
|
|
89
|
+
|
|
60
90
|
#### Ensuring deterministic results
|
|
91
|
+
|
|
61
92
|
Sorting has a fallback to an unique attribute which defaults to the `id` attribute. This ensures deterministic paginated
|
|
62
93
|
collection responses. You can override the `unique_sort_attribute` in the query object.
|
|
94
|
+
|
|
63
95
|
```ruby
|
|
64
96
|
# set the unique sort attribute
|
|
65
97
|
unique_sort_attribute :email
|
|
66
98
|
# use compound unique sort attributes
|
|
67
99
|
unique_sort_attributes :created_at, :email
|
|
68
100
|
````
|
|
101
|
+
|
|
69
102
|
#### Default sort options
|
|
103
|
+
|
|
70
104
|
The `default_sort` can be set to sort by any field like `created_at` timestamp or similar. It is only used if no sort
|
|
71
105
|
parameter is set, unlike the `unique_sort_attribute` which is always appended as the last sort attribute. The parameters
|
|
72
|
-
are passed directly to the underlying active record relation, so the usual ordering options are possible.
|
|
106
|
+
are passed directly to the underlying active record relation, so the usual ordering options are possible. It is also
|
|
107
|
+
possible to define the default sort with a lambda or by passing a sort object.
|
|
108
|
+
|
|
73
109
|
```ruby
|
|
110
|
+
default_sort :created_at
|
|
111
|
+
# or
|
|
74
112
|
default_sort created_at: :desc
|
|
113
|
+
# or
|
|
114
|
+
default_sort ->(collection) { collection.order(created_at: :desc) }
|
|
115
|
+
# or
|
|
116
|
+
default_sort SortObject
|
|
75
117
|
```
|
|
118
|
+
|
|
76
119
|
#### Enabling simple sorting for attributes
|
|
120
|
+
|
|
77
121
|
`sorts_by` denotes which attributes can be used for sorting. Sorting parameters are usually parsed from the
|
|
78
122
|
`json:api` sort query parameter in the order they are given. So `sort=-first_name,email` would translate to
|
|
79
|
-
`{ first_name: :desc, email: :asc }`
|
|
123
|
+
`{ first_name: :desc, email: :asc }`
|
|
124
|
+
|
|
80
125
|
```ruby
|
|
81
126
|
sorts_by :first_name
|
|
82
127
|
sorts_by :email
|
|
83
128
|
```
|
|
129
|
+
|
|
84
130
|
#### Sorting with lambdas
|
|
85
|
-
|
|
131
|
+
|
|
132
|
+
`sorts_by` also supports passing a lambda to implement a custom order or reorder function. The parameters passed to the
|
|
86
133
|
lamdba are collection and the direction of the order, which is either `:desc` or `:asc`.
|
|
134
|
+
|
|
87
135
|
```ruby
|
|
88
136
|
sorts_by :first_name, ->(collection, direction) { collection.order(name: direction) }
|
|
89
137
|
```
|
|
90
138
|
|
|
91
139
|
#### Sorting with sort classes
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
the current scope and the
|
|
140
|
+
|
|
141
|
+
But since we're devout followers of the SOLID principles, we can define a sort class that responds to `#results` method,
|
|
142
|
+
which returns the sorted collection. Under the hood the sort class is initialized with the current scope and the
|
|
143
|
+
direction parameter.
|
|
95
144
|
|
|
96
145
|
### Filtering
|
|
97
146
|
|
|
98
147
|
#### Simple exact match filters
|
|
148
|
+
|
|
99
149
|
```ruby
|
|
100
150
|
filters_by :first_name
|
|
101
151
|
# => collection.where(first_name: params.dig(:filter, :first_name)) if params.dig(:filter, :first_name).present?
|
|
102
152
|
```
|
|
103
153
|
|
|
104
154
|
#### Lambda as a filter
|
|
155
|
+
|
|
105
156
|
```ruby
|
|
106
157
|
filters_by :email, ->(collection, query) { collection.where('email ilike ?', "%#{query}%") }
|
|
107
158
|
# => collection.where('email ilike ?', "%#{params.dig(:filter, :email)}%") if params.dig(:filter, :email).present?
|
|
108
159
|
```
|
|
109
160
|
|
|
110
161
|
#### Filter classes
|
|
162
|
+
|
|
111
163
|
We can define a filter class that responds to `#results` method, which returns the filtered collection results. Under
|
|
112
164
|
the hood the filter class is initialized with the current scope and the query parameter. However, if the object responds
|
|
113
165
|
to a `call` method it sends the current scope and the query parameter to that instead. This is great if you're using
|
|
@@ -116,17 +168,23 @@ query objects for ActiveRecord scopes, you can easily use them to filter with as
|
|
|
116
168
|
```ruby
|
|
117
169
|
filters_by :type, TypeFilter
|
|
118
170
|
```
|
|
171
|
+
|
|
119
172
|
The filter class could look something like
|
|
173
|
+
|
|
120
174
|
```ruby
|
|
175
|
+
|
|
121
176
|
class TypeFilter < Jsonapi::QueryBuilder::BaseFilter
|
|
122
177
|
def results
|
|
123
178
|
collection.where(type: query.split(','))
|
|
124
179
|
end
|
|
125
180
|
end
|
|
126
181
|
```
|
|
182
|
+
|
|
127
183
|
Sometimes you need to perform in-memory filtering, for example when database attributes are encrypted. In that case,
|
|
128
184
|
those filters should be applied last, the order of definition in the query object matters.
|
|
185
|
+
|
|
129
186
|
```ruby
|
|
187
|
+
|
|
130
188
|
class MrnFilter < Jsonapi::QueryBuilder::BaseFilter
|
|
131
189
|
def results
|
|
132
190
|
collection.select { |record| /#{query}/.match?(record.mrn) }
|
|
@@ -135,26 +193,34 @@ end
|
|
|
135
193
|
```
|
|
136
194
|
|
|
137
195
|
#### Additional Options
|
|
196
|
+
|
|
138
197
|
You can override the filter query parameter name by passing the `query_parameter` option.
|
|
198
|
+
|
|
139
199
|
```ruby
|
|
140
200
|
filters_by :first_name, query_parameter: 'name'
|
|
141
201
|
# => collection.where(first_name: params.dig(:filter, :name)) if params.dig(:filter, :name).present?
|
|
142
202
|
```
|
|
203
|
+
|
|
143
204
|
`allow_nil` option changes the filter conditional to allow explicit checks for an attribute null value.
|
|
205
|
+
|
|
144
206
|
```ruby
|
|
145
207
|
filters_by :first_name, allow_nil: true
|
|
146
208
|
# => collection.where(first_name: params.dig(:filter, :first_name)) if params[:filter]&.key?(:first_name)
|
|
147
209
|
```
|
|
210
|
+
|
|
148
211
|
The conditional when the filter is applied can also be defined explicitly. Note that these options override the
|
|
149
212
|
`allow_nil` option, as the condition if defined explicitly and you should handle `nil` explicitly as well.
|
|
213
|
+
|
|
150
214
|
```ruby
|
|
151
215
|
filters_by :first_name, if: ->(query) { query.length >= 2 }
|
|
152
216
|
# => collection.where(first_name: params.dig(:filter, :first_name)) if params.dig(:filter, :first_name) >= 2
|
|
153
217
|
filters_by :first_name, unless: ->(query) { query.length < 2 }
|
|
154
218
|
# => collection.where(first_name: params.dig(:filter, :first_name)) unless params.dig(:filter, :first_name) < 2
|
|
155
219
|
```
|
|
220
|
+
|
|
156
221
|
When you're using a filter class you can pass a symbol to the `:if` and `:unless` options which invokes the method on
|
|
157
222
|
the filter class.
|
|
223
|
+
|
|
158
224
|
```ruby
|
|
159
225
|
filters_by :type, TypeFilter, if: :correct_type?
|
|
160
226
|
# => type_filter = TypeFilter.new(collection, query); type_filter.results if type_filter.correct_type?
|
|
@@ -176,7 +242,6 @@ version, push git commits and tags, and push the `.gem` file to [rubygems.org](h
|
|
|
176
242
|
|
|
177
243
|
Bug reports and pull requests are welcome on GitHub at https://github.com/infinum/jsonapi-query_builder.
|
|
178
244
|
|
|
179
|
-
|
|
180
245
|
## License
|
|
181
246
|
|
|
182
247
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -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
|
|
@@ -7,7 +7,7 @@ module Jsonapi
|
|
|
7
7
|
|
|
8
8
|
# @param [ActiveRecord::Relation] collection
|
|
9
9
|
# @param [Symbol] direction of the ordering, one of :asc or :desc
|
|
10
|
-
def initialize(collection, direction)
|
|
10
|
+
def initialize(collection, direction = :asc)
|
|
11
11
|
@collection = collection
|
|
12
12
|
@direction = direction
|
|
13
13
|
end
|
|
@@ -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,16 +79,12 @@ 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)
|
|
91
86
|
return collection if self.class._default_sort.nil? && sort_params.blank?
|
|
92
|
-
return collection
|
|
87
|
+
return sort_by_default(collection) if sort_params.blank?
|
|
93
88
|
|
|
94
89
|
sort_params.reduce(collection) do |sorted_collection, sort_param|
|
|
95
90
|
sort = self.class.supported_sorts.fetch(sort_param.attribute.to_sym)
|
|
@@ -102,6 +97,18 @@ module Jsonapi
|
|
|
102
97
|
end
|
|
103
98
|
end
|
|
104
99
|
|
|
100
|
+
def sort_by_default(collection)
|
|
101
|
+
default_sort = self.class._default_sort
|
|
102
|
+
|
|
103
|
+
if default_sort.is_a?(Symbol) || default_sort.is_a?(Hash)
|
|
104
|
+
collection.order(default_sort)
|
|
105
|
+
elsif default_sort.respond_to?(:call)
|
|
106
|
+
default_sort.call(collection)
|
|
107
|
+
else
|
|
108
|
+
default_sort.new(collection).results
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
105
112
|
def add_unique_order_attributes(collection)
|
|
106
113
|
collection.order(*self.class._unique_sort_attributes)
|
|
107
114
|
end
|
|
@@ -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.
|
|
4
|
+
version: 0.3.0
|
|
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-12-07 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,6 +216,8 @@ 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"
|
|
@@ -164,11 +236,17 @@ files:
|
|
|
164
236
|
- lib/jsonapi/query_builder/base_filter.rb
|
|
165
237
|
- lib/jsonapi/query_builder/base_query.rb
|
|
166
238
|
- lib/jsonapi/query_builder/base_sort.rb
|
|
239
|
+
- lib/jsonapi/query_builder/errors/unpermitted_sort_parameters.rb
|
|
167
240
|
- lib/jsonapi/query_builder/mixins/filter.rb
|
|
168
241
|
- lib/jsonapi/query_builder/mixins/include.rb
|
|
169
242
|
- lib/jsonapi/query_builder/mixins/paginate.rb
|
|
170
243
|
- lib/jsonapi/query_builder/mixins/sort.rb
|
|
171
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
|
|
172
250
|
- lib/jsonapi/query_builder/version.rb
|
|
173
251
|
homepage: https://github.com/infinum/jsonapi-query_builder
|
|
174
252
|
licenses:
|
|
@@ -186,16 +264,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
186
264
|
- - ">="
|
|
187
265
|
- !ruby/object:Gem::Version
|
|
188
266
|
version: '2.5'
|
|
189
|
-
- - "<="
|
|
190
|
-
- !ruby/object:Gem::Version
|
|
191
|
-
version: '3.0'
|
|
192
267
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
268
|
requirements:
|
|
194
269
|
- - ">="
|
|
195
270
|
- !ruby/object:Gem::Version
|
|
196
271
|
version: '0'
|
|
197
272
|
requirements: []
|
|
198
|
-
rubygems_version: 3.
|
|
273
|
+
rubygems_version: 3.2.22
|
|
199
274
|
signing_key:
|
|
200
275
|
specification_version: 4
|
|
201
276
|
summary: Support `json:api` querying with ease!
|