jsonapi-utils 0.3.5 → 0.4.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/.gitignore +3 -1
- data/README.md +4 -1
- data/jsonapi-utils.gemspec +8 -4
- data/lib/jsonapi/utils.rb +71 -111
- data/lib/jsonapi/utils/version.rb +1 -1
- metadata +50 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 768ad917f0e0006484fcca29a138f05c0b2f9a7b
|
4
|
+
data.tar.gz: 8be72ed0a02e3e86f0b73edd822a0f791992cb36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fd1c7fa5ca1e4c2d075be52fe75d058555a840fb0c70b43d94bf687f13fd7740d340f74f50fc6f64c4d90a171493c27425661ca26a6b7a99992472d697bc96a
|
7
|
+
data.tar.gz: 3a31efa4514d307eaccaf1c244db587cafccbca885bd2eafbbd8c846829a0d5ed0e4f86697a4e31b5cf46429e8f38b16bf4b0d16e85487dd52d09751ce94f4bc
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# JSONAPI::Utils
|
2
2
|
|
3
|
+
[](https://codeclimate.com/github/b2beauty/jsonapi-utils)
|
4
|
+
[](https://badge.fury.io/rb/jsonapi-utils)
|
5
|
+
|
3
6
|
JSON::Utils is a simple way to get a full-featured [JSON API](jsonapi.org) serialization in your
|
4
7
|
controller's responses. This gem works on top of the awesome gem [jsonapi-resources](https://github.com/cerebris/jsonapi-resources),
|
5
8
|
bringing to controllers a Rails-native way to render data.
|
@@ -9,7 +12,7 @@ bringing to controllers a Rails-native way to render data.
|
|
9
12
|
Add these lines to your application's Gemfile:
|
10
13
|
|
11
14
|
```ruby
|
12
|
-
gem 'jsonapi-resources', '~> 0.
|
15
|
+
gem 'jsonapi-resources', '~> 0.7.0'
|
13
16
|
gem 'jsonapi-utils'
|
14
17
|
```
|
15
18
|
|
data/jsonapi-utils.gemspec
CHANGED
@@ -10,20 +10,24 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["tiagopog@gmail.com", "douglas@beautydate.com.br"]
|
11
11
|
|
12
12
|
spec.summary = %q{JSON::Utils is a simple way to get a full-featured JSON API serialization for your controller's responses.}
|
13
|
-
spec.description = %q{A Rails way to get your API's data
|
13
|
+
spec.description = %q{A Rails way to get your API's data serialized through JSON API's specs (http://jsosapi.org)}
|
14
14
|
spec.homepage = "https://github.com/b2beauty/jsonapi-utils"
|
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)/}) }
|
18
18
|
spec.bindir = "exe"
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ['lib']
|
21
21
|
|
22
22
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
23
23
|
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'rspec'
|
24
25
|
spec.add_development_dependency 'rspec-rails'
|
26
|
+
spec.add_development_dependency 'smart_rspec'
|
27
|
+
spec.add_development_dependency 'pry'
|
25
28
|
spec.add_development_dependency 'sqlite3'
|
26
29
|
spec.add_development_dependency 'factory_girl', '~> 4.5'
|
27
|
-
spec.add_development_dependency 'jsonapi-resources', '~> 0.
|
28
|
-
|
30
|
+
spec.add_development_dependency 'jsonapi-resources', '~> 0.7.0'
|
31
|
+
|
32
|
+
spec.add_dependency 'rails', '>= 4.0'
|
29
33
|
end
|
data/lib/jsonapi/utils.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'jsonapi/utils/version'
|
2
|
+
require 'active_support/concern'
|
2
3
|
require 'jsonapi/utils/exceptions'
|
4
|
+
require 'pry'
|
3
5
|
|
4
6
|
module JSONAPI
|
5
7
|
module Utils
|
6
|
-
extend ActiveSupport::Concern
|
8
|
+
extend ::ActiveSupport::Concern
|
7
9
|
|
8
10
|
include do
|
9
11
|
helper_method :jsonapi_serialize
|
@@ -13,7 +15,14 @@ module JSONAPI
|
|
13
15
|
if options.has_key?(:json)
|
14
16
|
response = jsonapi_serialize(options[:json], options[:options] || {})
|
15
17
|
render json: response, status: options[:status] || :ok
|
18
|
+
else
|
19
|
+
raise ArgumentError.new('":json" key must be set to JSONAPI::Utils#jsonapi_render')
|
16
20
|
end
|
21
|
+
rescue => e
|
22
|
+
raise e unless e.class.name.starts_with?('JSONAPI::Exceptions')
|
23
|
+
handle_exceptions(e)
|
24
|
+
ensure
|
25
|
+
headers['Content-Type'] = JSONAPI::MEDIA_TYPE
|
17
26
|
end
|
18
27
|
|
19
28
|
def jsonapi_render_errors(exception)
|
@@ -33,8 +42,8 @@ module JSONAPI
|
|
33
42
|
jsonapi_render_errors(::JSONAPI::Utils::Exceptions::BadRequest.new)
|
34
43
|
end
|
35
44
|
|
36
|
-
def jsonapi_render_not_found
|
37
|
-
id =
|
45
|
+
def jsonapi_render_not_found
|
46
|
+
id = extract_ids(@request.params)
|
38
47
|
jsonapi_render_errors(JSONAPI::Exceptions::RecordNotFound.new(id))
|
39
48
|
end
|
40
49
|
|
@@ -43,17 +52,18 @@ module JSONAPI
|
|
43
52
|
end
|
44
53
|
|
45
54
|
def jsonapi_serialize(records, options = {})
|
55
|
+
setup_request
|
46
56
|
results = JSONAPI::OperationResults.new
|
47
57
|
|
48
58
|
fix_request_options(params, records)
|
49
59
|
|
50
60
|
if records.respond_to?(:to_ary)
|
51
|
-
records
|
52
|
-
@
|
53
|
-
results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, @
|
61
|
+
records = fix_when_hash(records, options) if needs_to_be_fixed?(records)
|
62
|
+
@resources = build_collection(records, options)
|
63
|
+
results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, @resources, result_options(options)))
|
54
64
|
else
|
55
|
-
@
|
56
|
-
results.add_result(JSONAPI::ResourceOperationResult.new(:ok, @
|
65
|
+
@resource = turn_into_resource(records, options)
|
66
|
+
results.add_result(JSONAPI::ResourceOperationResult.new(:ok, @resource))
|
57
67
|
end
|
58
68
|
|
59
69
|
create_response_document(results).contents
|
@@ -61,6 +71,11 @@ module JSONAPI
|
|
61
71
|
|
62
72
|
private
|
63
73
|
|
74
|
+
def extract_ids(hash)
|
75
|
+
ids = hash.keys.select { |e| e =~ /id$/i }.map { |e| hash[e] }
|
76
|
+
ids.first rescue '(id not identified)'
|
77
|
+
end
|
78
|
+
|
64
79
|
def fix_request_options(params, records)
|
65
80
|
return if request.method !~ /get/i ||
|
66
81
|
params.nil? ||
|
@@ -73,142 +88,87 @@ module JSONAPI
|
|
73
88
|
records.is_a?(Array) && records.all? { |e| e.is_a?(Hash) }
|
74
89
|
end
|
75
90
|
|
76
|
-
def result_options(
|
77
|
-
{}
|
78
|
-
if JSONAPI.configuration.top_level_links_include_pagination
|
79
|
-
data[:pagination_params] = pagination_params(records, options)
|
80
|
-
end
|
91
|
+
def result_options(options)
|
92
|
+
hash = {}
|
81
93
|
|
82
|
-
|
83
|
-
|
84
|
-
end
|
94
|
+
if JSONAPI.configuration.top_level_links_include_pagination
|
95
|
+
hash[:pagination_params] = pagination_params(options)
|
85
96
|
end
|
86
|
-
end
|
87
97
|
|
88
|
-
|
89
|
-
|
90
|
-
if @_paginator && JSONAPI.configuration.top_level_links_include_pagination
|
91
|
-
@_paginator.class.requires_record_count &&
|
92
|
-
data[:record_count] = count_records(records, options)
|
93
|
-
@_paginator.links_page_params(data)
|
94
|
-
else
|
95
|
-
data
|
98
|
+
if JSONAPI.configuration.top_level_meta_include_record_count
|
99
|
+
hash[:record_count] = count_records(@resources, options)
|
96
100
|
end
|
97
|
-
end
|
98
101
|
|
99
|
-
|
100
|
-
records = apply_filter(records, options)
|
101
|
-
records = apply_pagination(records, options)
|
102
|
-
records = apply_sort(records)
|
103
|
-
records.respond_to?(:to_ary) ? records.map { |record| turn_into_resource(record, options) } : []
|
102
|
+
hash
|
104
103
|
end
|
105
104
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
105
|
+
def pagination_params(options)
|
106
|
+
@paginator ||= paginator(params)
|
107
|
+
if @paginator && JSONAPI.configuration.top_level_links_include_pagination
|
108
|
+
options = {}
|
109
|
+
@paginator.class.requires_record_count &&
|
110
|
+
options[:record_count] = count_records(@resources, options)
|
111
|
+
@paginator.links_page_params(options)
|
109
112
|
else
|
110
|
-
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def apply_filter(records, options = {})
|
115
|
-
if apply_filter?(records, options)
|
116
|
-
records.where(filter_params)
|
117
|
-
else
|
118
|
-
records
|
113
|
+
{}
|
119
114
|
end
|
120
115
|
end
|
121
116
|
|
122
|
-
def
|
123
|
-
|
124
|
-
(options[:filter].nil? || options[:filter])
|
125
|
-
end
|
126
|
-
|
127
|
-
def filter_params
|
128
|
-
@_filter_params =
|
129
|
-
params[:filter].keys.each_with_object({}) do |resource, hash|
|
130
|
-
hash[resource] = params[:filter][resource]
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def apply_pagination(records, options = {})
|
135
|
-
return records unless apply_pagination?(options)
|
136
|
-
pagination = set_pagination(options)
|
117
|
+
def paginator(params)
|
118
|
+
page_params = ActionController::Parameters.new(params[:page])
|
137
119
|
|
138
|
-
|
139
|
-
if
|
140
|
-
|
141
|
-
|
142
|
-
|
120
|
+
@paginator ||=
|
121
|
+
if JSONAPI.configuration.default_paginator == :paged
|
122
|
+
PagedPaginator.new(page_params)
|
123
|
+
elsif JSONAPI.configuration.default_paginator == :offset
|
124
|
+
OffsetPaginator.new(page_params)
|
143
125
|
end
|
144
126
|
end
|
145
127
|
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
if records.is_a?(Array)
|
150
|
-
records.sort { |a, b| comp = 0; eval(sort_criteria) }
|
151
|
-
elsif records.respond_to?(:order)
|
152
|
-
records.order(sort_params)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def sort_criteria
|
157
|
-
sort_params.reduce('') do |sum, hash|
|
158
|
-
foo = ["a[:#{hash[0]}]", "b[:#{hash[0]}]"]
|
159
|
-
foo.reverse! if hash[1] == :desc
|
160
|
-
sum + "comp = comp == 0 ? #{foo.join(' <=> ')} : comp; "
|
128
|
+
def build_collection(records, options = {})
|
129
|
+
unless JSONAPI.configuration.default_paginator == :none
|
130
|
+
records = paginator(@request.params).apply(records, nil)
|
161
131
|
end
|
132
|
+
records.respond_to?(:to_ary) ? records.map { |record| turn_into_resource(record, options) } : []
|
162
133
|
end
|
163
134
|
|
164
|
-
def
|
165
|
-
|
166
|
-
|
167
|
-
order, field = criteria.match(/(\-?)(\w+)/i)[1..2]
|
168
|
-
hash[field] = order == '-' ? :desc : :asc
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def set_pagination(options)
|
173
|
-
page_params = ActionController::Parameters.new(@request.params[:page])
|
174
|
-
if JSONAPI.configuration.default_paginator == :paged
|
175
|
-
@_paginator ||= PagedPaginator.new(page_params)
|
176
|
-
number = page_params['number'].to_i.nonzero? || 1
|
177
|
-
size = page_params['size'].to_i.nonzero? || JSONAPI.configuration.default_page_size
|
178
|
-
{ paginator: @_paginator, range: (number - 1) * size..number * size - 1 }
|
179
|
-
elsif JSONAPI.configuration.default_paginator == :offset
|
180
|
-
@_paginator ||= OffsetPaginator.new(page_params)
|
181
|
-
offset = page_params['offset'].to_i.nonzero? || 0
|
182
|
-
limit = page_params['limit'].to_i.nonzero? || JSONAPI.configuration.default_page_size
|
183
|
-
{ paginator: @_paginator, range: offset..offset + limit - 1 }
|
135
|
+
def turn_into_resource(record, options = {})
|
136
|
+
if options[:resource]
|
137
|
+
options[:resource].to_s.constantize.new(record, context)
|
184
138
|
else
|
185
|
-
|
139
|
+
@request.resource_klass.new(record, context)
|
186
140
|
end
|
187
141
|
end
|
188
142
|
|
189
|
-
def apply_pagination?(options)
|
190
|
-
JSONAPI.configuration.default_paginator != :none &&
|
191
|
-
(options[:paginate].nil? || options[:paginate])
|
192
|
-
end
|
193
|
-
|
194
143
|
def fix_when_hash(records, options)
|
195
144
|
return [] unless options[:model]
|
196
145
|
records.map { |hash| options[:model].new(hash) }
|
197
|
-
rescue
|
146
|
+
rescue
|
198
147
|
ids = records.map { |e| e[:id] || e['id'] }
|
199
148
|
scope = options[:scope] ? options[:model].send(options[:scope]) : options[:model]
|
200
149
|
scope.where(id: ids)
|
201
150
|
end
|
202
151
|
|
203
152
|
def count_records(records, options)
|
204
|
-
if
|
205
|
-
|
206
|
-
elsif
|
207
|
-
|
153
|
+
if records.size.zero? then 0
|
154
|
+
elsif options[:count] then options[:count]
|
155
|
+
elsif options[:model] && options[:scope] then options[:model].send(options[:scope]).count
|
156
|
+
elsif options[:model] then options[:model].count
|
208
157
|
else
|
209
|
-
|
210
|
-
|
158
|
+
record = records.first
|
159
|
+
model = record.try(:model) || record.try(:_model)
|
160
|
+
model.class.count
|
211
161
|
end
|
212
162
|
end
|
163
|
+
|
164
|
+
def setup_request
|
165
|
+
@request ||=
|
166
|
+
JSONAPI::Request.new(
|
167
|
+
params,
|
168
|
+
context: context,
|
169
|
+
key_formatter: key_formatter,
|
170
|
+
server_error_callbacks: (self.class.server_error_callbacks || [])
|
171
|
+
)
|
172
|
+
end
|
213
173
|
end
|
214
174
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Guedes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -39,6 +39,20 @@ dependencies:
|
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: rspec-rails
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,6 +67,34 @@ dependencies:
|
|
53
67
|
- - ">="
|
54
68
|
- !ruby/object:Gem::Version
|
55
69
|
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: smart_rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: pry
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
56
98
|
- !ruby/object:Gem::Dependency
|
57
99
|
name: sqlite3
|
58
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,14 +129,14 @@ dependencies:
|
|
87
129
|
requirements:
|
88
130
|
- - "~>"
|
89
131
|
- !ruby/object:Gem::Version
|
90
|
-
version: 0.
|
132
|
+
version: 0.7.0
|
91
133
|
type: :development
|
92
134
|
prerelease: false
|
93
135
|
version_requirements: !ruby/object:Gem::Requirement
|
94
136
|
requirements:
|
95
137
|
- - "~>"
|
96
138
|
- !ruby/object:Gem::Version
|
97
|
-
version: 0.
|
139
|
+
version: 0.7.0
|
98
140
|
- !ruby/object:Gem::Dependency
|
99
141
|
name: rails
|
100
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,14 +144,15 @@ dependencies:
|
|
102
144
|
- - ">="
|
103
145
|
- !ruby/object:Gem::Version
|
104
146
|
version: '4.0'
|
105
|
-
type: :
|
147
|
+
type: :runtime
|
106
148
|
prerelease: false
|
107
149
|
version_requirements: !ruby/object:Gem::Requirement
|
108
150
|
requirements:
|
109
151
|
- - ">="
|
110
152
|
- !ruby/object:Gem::Version
|
111
153
|
version: '4.0'
|
112
|
-
description: A Rails way to get your API's data
|
154
|
+
description: A Rails way to get your API's data serialized through JSON API's specs
|
155
|
+
(http://jsosapi.org)
|
113
156
|
email:
|
114
157
|
- tiagopog@gmail.com
|
115
158
|
- douglas@beautydate.com.br
|
@@ -151,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
194
|
version: '0'
|
152
195
|
requirements: []
|
153
196
|
rubyforge_project:
|
154
|
-
rubygems_version: 2.
|
197
|
+
rubygems_version: 2.4.5.1
|
155
198
|
signing_key:
|
156
199
|
specification_version: 4
|
157
200
|
summary: JSON::Utils is a simple way to get a full-featured JSON API serialization
|