jsonapi-utils 0.5.0.beta3 → 0.5.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -1
- data/lib/jsonapi/utils/support/filter/default.rb +36 -2
- data/lib/jsonapi/utils/support/pagination.rb +16 -7
- data/lib/jsonapi/utils/support/sort.rb +45 -28
- data/lib/jsonapi/utils/version.rb +1 -1
- metadata +30 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68e34821e946ce803f78ad83fa6515c99dd7e847
|
4
|
+
data.tar.gz: 52e3849ce3f372eeed8276e4c2ba62815e413e30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b2c8f3ac88c7571ca61148f657de7ffbdf8607a4e22a4136f877801cb2be8ff2e74ba1031c8beec5133fea62d8dad5be1f7199310a9a0011149c035c893d09b
|
7
|
+
data.tar.gz: f9b02d37f90f04e7e2c224381ace8744127173a9fdba7ce05b1ae8992a4476ca01a59ae8f12dd4de390c17ec4f05009767846af4781806a2de4359904ca0e1c8
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@ Simple yet powerful way to get your Rails API compliant with [JSON API](http://j
|
|
16
16
|
* [Response](#response)
|
17
17
|
* [Renders](#renders)
|
18
18
|
* [Formatters](#formatters)
|
19
|
+
* [Paginators](#paginators)
|
19
20
|
* [Request](#request)
|
20
21
|
* [Params helpers](#params-helpers)
|
21
22
|
* [Full example](#full-example)
|
@@ -50,7 +51,7 @@ gem 'jsonapi-utils', '~> 0.4.6'
|
|
50
51
|
For Rails 5, specify the beta version in the Gemfile:
|
51
52
|
|
52
53
|
```ruby
|
53
|
-
gem 'jsonapi-utils', '0.5.0.
|
54
|
+
gem 'jsonapi-utils', '0.5.0.beta3'
|
54
55
|
```
|
55
56
|
|
56
57
|
And then execute:
|
@@ -176,6 +177,28 @@ Arguments:
|
|
176
177
|
- First: ActiveRecord object, Hash or Array of Hashes;
|
177
178
|
- Last: Hash of options (same as `JSONAPI::Utils#jsonapi_render`).
|
178
179
|
|
180
|
+
#### Paginators
|
181
|
+
|
182
|
+
If you are rendering a collection of hashes, you'll need to implement the `#pagination_range` method, which returns a range for your resources. For example:
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
class CustomPaginator < JSONAPI::Paginator
|
186
|
+
def pagination_range(page_params)
|
187
|
+
offset = page_params['offset']
|
188
|
+
limit = JSONAPI.configuration.default_page_size
|
189
|
+
offset..offset + limit - 1
|
190
|
+
end
|
191
|
+
```
|
192
|
+
|
193
|
+
And then it can be either set at the resource class level (e.g. UserResource.paginator :custom_paginator) or via config initializer:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
# config/initializers/jsonapi_resources.rb
|
197
|
+
JSONAPI.configure do |config|
|
198
|
+
config.default_paginator = :custom_paginator
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
179
202
|
### Request
|
180
203
|
|
181
204
|
Before a controller's action gets executed, `JSONAPI::Utils` will validate the request against JSON API specifications as well as evaluating the eventual query string params to check if they match the resource's definition. If something goes wrong during the validation process, JU will render an error response like this examples below:
|
@@ -1,5 +1,17 @@
|
|
1
1
|
module JSONAPI::Utils::Support::Filter
|
2
2
|
module Default
|
3
|
+
# Apply default equality filters.
|
4
|
+
# e.g.: User.where(name: 'Foobar')
|
5
|
+
#
|
6
|
+
# @param records [ActiveRecord::Relation, Array] collection of records
|
7
|
+
# e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
|
8
|
+
#
|
9
|
+
# @param options [Hash] JU's options
|
10
|
+
# e.g.: { filter: false, paginate: false }
|
11
|
+
#
|
12
|
+
# @return [ActiveRecord::Relation, Array]
|
13
|
+
#
|
14
|
+
# @api public
|
3
15
|
def apply_filter(records, options = {})
|
4
16
|
if apply_filter?(records, options)
|
5
17
|
records.where(filter_params)
|
@@ -8,23 +20,45 @@ module JSONAPI::Utils::Support::Filter
|
|
8
20
|
end
|
9
21
|
end
|
10
22
|
|
23
|
+
# Check whether default filters should be applied.
|
24
|
+
#
|
25
|
+
# @param records [ActiveRecord::Relation, Array] collection of records
|
26
|
+
# e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
|
27
|
+
#
|
28
|
+
# @param options [Hash] JU's options
|
29
|
+
# e.g.: { filter: false, paginate: false }
|
30
|
+
#
|
31
|
+
# @return [Boolean]
|
32
|
+
#
|
33
|
+
# @api public
|
11
34
|
def apply_filter?(records, options = {})
|
12
35
|
params[:filter].present? && records.respond_to?(:where) &&
|
13
36
|
(options[:filter].nil? || options[:filter])
|
14
37
|
end
|
15
38
|
|
39
|
+
# Build a Hash with the default filters.
|
40
|
+
#
|
41
|
+
# @return [Hash, NilClass]
|
42
|
+
#
|
43
|
+
# @api public
|
16
44
|
def filter_params
|
17
45
|
@_filter_params ||=
|
18
46
|
case params[:filter]
|
19
47
|
when Hash, ActionController::Parameters
|
20
|
-
default_filters.each_with_object({}) do |
|
21
|
-
|
48
|
+
default_filters.each_with_object({}) do |field, hash|
|
49
|
+
unformatted_field = @request.unformat_key(field)
|
50
|
+
hash[unformatted_field] = params[:filter][field]
|
22
51
|
end
|
23
52
|
end
|
24
53
|
end
|
25
54
|
|
26
55
|
private
|
27
56
|
|
57
|
+
# Take all allowed filters and remove the custom ones.
|
58
|
+
#
|
59
|
+
# @return [Array]
|
60
|
+
#
|
61
|
+
# @api private
|
28
62
|
def default_filters
|
29
63
|
params[:filter].keys.map(&:to_sym) - @request.resource_klass._custom_filters
|
30
64
|
end
|
@@ -44,12 +44,16 @@ module JSONAPI
|
|
44
44
|
#
|
45
45
|
# @api private
|
46
46
|
def paginator
|
47
|
-
@paginator ||=
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
@paginator ||= paginator_klass.new(page_params)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the paginator class to be used in the response's pagination.
|
51
|
+
#
|
52
|
+
# @return [Paginator]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def paginator_klass
|
56
|
+
"#{JSONAPI.configuration.default_paginator}_paginator".classify.constantize
|
53
57
|
end
|
54
58
|
|
55
59
|
# Check whether pagination should be applied to the response.
|
@@ -68,7 +72,10 @@ module JSONAPI
|
|
68
72
|
#
|
69
73
|
# @api private
|
70
74
|
def page_params
|
71
|
-
@page_params ||=
|
75
|
+
@page_params ||= begin
|
76
|
+
page = @request.params.to_unsafe_hash['page'] || {}
|
77
|
+
ActionController::Parameters.new(page)
|
78
|
+
end
|
72
79
|
end
|
73
80
|
|
74
81
|
# Define the paginator or range according to the pagination strategy.
|
@@ -105,6 +112,8 @@ module JSONAPI
|
|
105
112
|
offset = page_params['offset'].to_i.nonzero? || 0
|
106
113
|
limit = page_params['limit'].to_i.nonzero? || JSONAPI.configuration.default_page_size
|
107
114
|
offset..offset + limit - 1
|
115
|
+
else
|
116
|
+
paginator.pagination_range(page_params)
|
108
117
|
end
|
109
118
|
end
|
110
119
|
|
@@ -1,36 +1,53 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module JSONAPI::Utils::Support
|
2
|
+
module Sort
|
3
|
+
# Apply sort on result set (ascending by default).
|
4
|
+
# e.g.: User.order(:first_name)
|
5
|
+
#
|
6
|
+
# @param records [ActiveRecord::Relation, Array] collection of records
|
7
|
+
# e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
|
8
|
+
#
|
9
|
+
# @return [ActiveRecord::Relation, Array]
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
def apply_sort(records)
|
13
|
+
return records unless params[:sort].present?
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
if records.is_a?(Array)
|
16
|
+
records.sort { |a, b| comp = 0; eval(sort_criteria) }
|
17
|
+
elsif records.respond_to?(:order)
|
18
|
+
records.order(sort_params)
|
19
|
+
end
|
20
|
+
end
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
# Build the criteria to be evaluated wthen applying sort
|
23
|
+
# on Array of Hashes (ascending by default).
|
24
|
+
#
|
25
|
+
# @return [String]
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
def sort_criteria
|
29
|
+
@sort_criteria ||=
|
30
|
+
sort_params.reduce('') do |sum, (key, value)|
|
31
|
+
comparables = ["a[:#{key}]", "b[:#{key}]"]
|
32
|
+
comparables.reverse! if value == :desc
|
33
|
+
sum + "comp = comp == 0 ? #{comparables.join(' <=> ')} : comp; "
|
22
34
|
end
|
35
|
+
end
|
23
36
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
37
|
+
# Build a Hash with the sort criteria.
|
38
|
+
#
|
39
|
+
# @return [Hash, NilClass]
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def sort_params
|
43
|
+
@_sort_params ||=
|
44
|
+
if params[:sort].present?
|
45
|
+
params[:sort].split(',').each_with_object({}) do |field, hash|
|
46
|
+
unformatted_field = @request.unformat_key(field)
|
47
|
+
desc, field = unformatted_field.to_s.match(/^([-_])?(\w+)$/i)[1..2]
|
48
|
+
hash[field] = desc.present? ? :desc : :asc
|
49
|
+
end
|
32
50
|
end
|
33
|
-
end
|
34
51
|
end
|
35
52
|
end
|
36
53
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.0.
|
4
|
+
version: 0.5.0.beta4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Guedes
|
@@ -9,146 +9,146 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-10-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jsonapi-resources
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - ~>
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 0.8.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - ~>
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 0.8.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: bundler
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - ~>
|
32
|
+
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '1.10'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - ~>
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '1.10'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rake
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - ~>
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '10.0'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - ~>
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '10.0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: sqlite3
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '0'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rails
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - ~>
|
74
|
+
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '4.2'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- - ~>
|
81
|
+
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '4.2'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rspec-rails
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - ~>
|
88
|
+
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '3.1'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - ~>
|
95
|
+
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '3.1'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: factory_girl
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - ~>
|
102
|
+
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '4.5'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - ~>
|
109
|
+
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '4.5'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: smart_rspec
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- - ~>
|
116
|
+
- - "~>"
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: 0.1.4
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- - ~>
|
123
|
+
- - "~>"
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: 0.1.4
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: pry
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- - ~>
|
130
|
+
- - "~>"
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: 0.10.3
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- - ~>
|
137
|
+
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: 0.10.3
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: pry-byebug
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- -
|
144
|
+
- - ">="
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
type: :development
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
|
-
- -
|
151
|
+
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
description: A Rails way to get your API's data serialized through JSON API's specs
|
@@ -160,24 +160,24 @@ executables: []
|
|
160
160
|
extensions: []
|
161
161
|
extra_rdoc_files: []
|
162
162
|
files:
|
163
|
+
- CODE_OF_CONDUCT.md
|
164
|
+
- LICENSE.txt
|
165
|
+
- README.md
|
163
166
|
- bin/console
|
164
167
|
- bin/setup
|
168
|
+
- lib/jsonapi/utils.rb
|
165
169
|
- lib/jsonapi/utils/exceptions.rb
|
166
170
|
- lib/jsonapi/utils/request.rb
|
171
|
+
- lib/jsonapi/utils/response.rb
|
167
172
|
- lib/jsonapi/utils/response/formatters.rb
|
168
173
|
- lib/jsonapi/utils/response/renders.rb
|
169
174
|
- lib/jsonapi/utils/response/support.rb
|
170
|
-
- lib/jsonapi/utils/response.rb
|
171
175
|
- lib/jsonapi/utils/support/error.rb
|
172
176
|
- lib/jsonapi/utils/support/filter/custom.rb
|
173
177
|
- lib/jsonapi/utils/support/filter/default.rb
|
174
178
|
- lib/jsonapi/utils/support/pagination.rb
|
175
179
|
- lib/jsonapi/utils/support/sort.rb
|
176
180
|
- lib/jsonapi/utils/version.rb
|
177
|
-
- lib/jsonapi/utils.rb
|
178
|
-
- LICENSE.txt
|
179
|
-
- README.md
|
180
|
-
- CODE_OF_CONDUCT.md
|
181
181
|
homepage: https://github.com/b2beauty/jsonapi-utils
|
182
182
|
licenses:
|
183
183
|
- MIT
|
@@ -188,17 +188,17 @@ require_paths:
|
|
188
188
|
- lib
|
189
189
|
required_ruby_version: !ruby/object:Gem::Requirement
|
190
190
|
requirements:
|
191
|
-
- -
|
191
|
+
- - ">="
|
192
192
|
- !ruby/object:Gem::Version
|
193
193
|
version: '0'
|
194
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
195
|
requirements:
|
196
|
-
- -
|
196
|
+
- - ">"
|
197
197
|
- !ruby/object:Gem::Version
|
198
198
|
version: 1.3.1
|
199
199
|
requirements: []
|
200
200
|
rubyforge_project:
|
201
|
-
rubygems_version: 2.
|
201
|
+
rubygems_version: 2.5.1
|
202
202
|
signing_key:
|
203
203
|
specification_version: 4
|
204
204
|
summary: JSON::Utils is a simple way to get a full-featured JSON API serialization
|