jsonapi-resources 0.9.11 → 0.10.7
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/LICENSE.txt +1 -1
- data/README.md +34 -11
- data/lib/bug_report_templates/rails_5_latest.rb +125 -0
- data/lib/bug_report_templates/rails_5_master.rb +140 -0
- data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +27 -0
- data/lib/jsonapi/active_relation/join_manager.rb +303 -0
- data/lib/jsonapi/active_relation_resource.rb +884 -0
- data/lib/jsonapi/acts_as_resource_controller.rb +122 -106
- data/lib/jsonapi/basic_resource.rb +1162 -0
- data/lib/jsonapi/cached_response_fragment.rb +127 -0
- data/lib/jsonapi/compiled_json.rb +11 -1
- data/lib/jsonapi/configuration.rb +57 -8
- data/lib/jsonapi/error.rb +27 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +63 -40
- data/lib/jsonapi/formatter.rb +3 -3
- data/lib/jsonapi/include_directives.rb +18 -75
- data/lib/jsonapi/link_builder.rb +16 -19
- data/lib/jsonapi/operation.rb +16 -5
- data/lib/jsonapi/operation_result.rb +73 -15
- data/lib/jsonapi/paginator.rb +17 -0
- data/lib/jsonapi/path.rb +43 -0
- data/lib/jsonapi/path_segment.rb +76 -0
- data/lib/jsonapi/processor.rb +246 -111
- data/lib/jsonapi/relationship.rb +117 -18
- data/lib/jsonapi/request_parser.rb +383 -396
- data/lib/jsonapi/resource.rb +3 -1376
- data/lib/jsonapi/resource_controller_metal.rb +5 -2
- data/lib/jsonapi/resource_fragment.rb +47 -0
- data/lib/jsonapi/resource_id_tree.rb +112 -0
- data/lib/jsonapi/resource_identity.rb +42 -0
- data/lib/jsonapi/resource_serializer.rb +124 -286
- data/lib/jsonapi/resource_set.rb +176 -0
- data/lib/jsonapi/resources/railtie.rb +9 -0
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +104 -87
- data/lib/jsonapi/routing_ext.rb +19 -21
- data/lib/jsonapi-resources.rb +20 -4
- data/lib/tasks/check_upgrade.rake +52 -0
- metadata +36 -33
- data/lib/jsonapi/cached_resource_fragment.rb +0 -127
- data/lib/jsonapi/operation_dispatcher.rb +0 -88
- data/lib/jsonapi/operation_results.rb +0 -35
- data/lib/jsonapi/relationship_builder.rb +0 -167
@@ -0,0 +1,127 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
class CachedResponseFragment
|
3
|
+
|
4
|
+
Lookup = Struct.new(:resource_klass, :serializer_config_key, :context, :context_key, :cache_ids) do
|
5
|
+
|
6
|
+
def type
|
7
|
+
resource_klass._type
|
8
|
+
end
|
9
|
+
|
10
|
+
def keys
|
11
|
+
cache_ids.map do |(id, cache_key)|
|
12
|
+
[type, id, cache_key, serializer_config_key, context_key]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Write = Struct.new(:resource_klass, :resource, :serializer, :serializer_config_key, :context, :context_key, :relationship_data) do
|
18
|
+
def to_key_value
|
19
|
+
|
20
|
+
(id, cache_key) = resource.cache_id
|
21
|
+
|
22
|
+
json = serializer.object_hash(resource, relationship_data)
|
23
|
+
|
24
|
+
cr = CachedResponseFragment.new(
|
25
|
+
resource_klass,
|
26
|
+
id,
|
27
|
+
json['type'],
|
28
|
+
context,
|
29
|
+
resource.fetchable_fields,
|
30
|
+
json['relationships'],
|
31
|
+
json['links'],
|
32
|
+
json['attributes'],
|
33
|
+
json['meta']
|
34
|
+
)
|
35
|
+
|
36
|
+
key = [resource_klass._type, id, cache_key, serializer_config_key, context_key]
|
37
|
+
|
38
|
+
[key, cr]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :resource_klass, :id, :type, :context, :fetchable_fields, :relationships,
|
43
|
+
:links_json, :attributes_json, :meta_json
|
44
|
+
|
45
|
+
def initialize(resource_klass, id, type, context, fetchable_fields, relationships,
|
46
|
+
links_json, attributes_json, meta_json)
|
47
|
+
@resource_klass = resource_klass
|
48
|
+
@id = id
|
49
|
+
@type = type
|
50
|
+
@context = context
|
51
|
+
@fetchable_fields = Set.new(fetchable_fields)
|
52
|
+
|
53
|
+
# Relationships left uncompiled because we'll often want to insert included ids on retrieval
|
54
|
+
# Remove the data since that should not be cached
|
55
|
+
@relationships = relationships&.transform_values {|v| v.delete_if {|k, _v| k == 'data'} }
|
56
|
+
@links_json = CompiledJson.of(links_json)
|
57
|
+
@attributes_json = CompiledJson.of(attributes_json)
|
58
|
+
@meta_json = CompiledJson.of(meta_json)
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_cache_value
|
62
|
+
{
|
63
|
+
id: id,
|
64
|
+
type: type,
|
65
|
+
fetchable: fetchable_fields,
|
66
|
+
rels: relationships,
|
67
|
+
links: links_json.try(:to_s),
|
68
|
+
attrs: attributes_json.try(:to_s),
|
69
|
+
meta: meta_json.try(:to_s)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param [Lookup[]] lookups
|
74
|
+
# @return [Hash<Class<Resource>, Hash<ID, CachedResourceFragment>>]
|
75
|
+
def self.lookup(lookups, context)
|
76
|
+
type_to_klass = lookups.map {|l| [l.type, l.resource_klass]}.to_h
|
77
|
+
|
78
|
+
keys = lookups.map(&:keys).flatten(1)
|
79
|
+
|
80
|
+
hits = JSONAPI.configuration.resource_cache.read_multi(*keys).reject {|_, v| v.nil?}
|
81
|
+
|
82
|
+
return keys.inject({}) do |hash, key|
|
83
|
+
(type, id, _, _) = key
|
84
|
+
resource_klass = type_to_klass[type]
|
85
|
+
hash[resource_klass] ||= {}
|
86
|
+
|
87
|
+
if hits.has_key?(key)
|
88
|
+
hash[resource_klass][id] = self.from_cache_value(resource_klass, context, hits[key])
|
89
|
+
else
|
90
|
+
hash[resource_klass][id] = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
hash
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [Write[]] lookups
|
98
|
+
def self.write(writes)
|
99
|
+
key_values = writes.map(&:to_key_value)
|
100
|
+
|
101
|
+
to_write = key_values.map {|(k, v)| [k, v.to_cache_value]}.to_h
|
102
|
+
|
103
|
+
if JSONAPI.configuration.resource_cache.respond_to? :write_multi
|
104
|
+
JSONAPI.configuration.resource_cache.write_multi(to_write)
|
105
|
+
else
|
106
|
+
to_write.each do |key, value|
|
107
|
+
JSONAPI.configuration.resource_cache.write(key, value)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.from_cache_value(resource_klass, context, h)
|
114
|
+
new(
|
115
|
+
resource_klass,
|
116
|
+
h.fetch(:id),
|
117
|
+
h.fetch(:type),
|
118
|
+
context,
|
119
|
+
h.fetch(:fetchable),
|
120
|
+
h.fetch(:rels, nil),
|
121
|
+
h.fetch(:links, nil),
|
122
|
+
h.fetch(:attrs, nil),
|
123
|
+
h.fetch(:meta, nil)
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -5,6 +5,7 @@ module JSONAPI
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.of(obj)
|
8
|
+
# :nocov:
|
8
9
|
case obj
|
9
10
|
when NilClass then nil
|
10
11
|
when CompiledJson then obj
|
@@ -12,6 +13,7 @@ module JSONAPI
|
|
12
13
|
when Hash then CompiledJson.compile(obj)
|
13
14
|
else raise "Can't figure out how to turn #{obj.inspect} into CompiledJson"
|
14
15
|
end
|
16
|
+
# :nocov:
|
15
17
|
end
|
16
18
|
|
17
19
|
def initialize(json, h = nil)
|
@@ -19,7 +21,7 @@ module JSONAPI
|
|
19
21
|
@h = h
|
20
22
|
end
|
21
23
|
|
22
|
-
def to_json(*
|
24
|
+
def to_json(*_args)
|
23
25
|
@json
|
24
26
|
end
|
25
27
|
|
@@ -27,9 +29,17 @@ module JSONAPI
|
|
27
29
|
@json
|
28
30
|
end
|
29
31
|
|
32
|
+
# :nocov:
|
30
33
|
def to_h
|
31
34
|
@h ||= JSON.parse(@json)
|
32
35
|
end
|
36
|
+
# :nocov:
|
37
|
+
|
38
|
+
def [](key)
|
39
|
+
# :nocov:
|
40
|
+
to_h[key]
|
41
|
+
# :nocov:
|
42
|
+
end
|
33
43
|
|
34
44
|
undef_method :as_json
|
35
45
|
end
|
@@ -8,14 +8,17 @@ module JSONAPI
|
|
8
8
|
:resource_key_type,
|
9
9
|
:route_format,
|
10
10
|
:raise_if_parameters_not_allowed,
|
11
|
+
:warn_on_route_setup_issues,
|
11
12
|
:warn_on_missing_routes,
|
12
|
-
:
|
13
|
+
:warn_on_performance_issues,
|
14
|
+
:default_allow_include_to_one,
|
15
|
+
:default_allow_include_to_many,
|
13
16
|
:allow_sort,
|
14
17
|
:allow_filter,
|
15
18
|
:default_paginator,
|
16
19
|
:default_page_size,
|
17
20
|
:maximum_page_size,
|
18
|
-
:
|
21
|
+
:default_processor_klass_name,
|
19
22
|
:use_text_errors,
|
20
23
|
:top_level_links_include_pagination,
|
21
24
|
:top_level_meta_include_record_count,
|
@@ -24,6 +27,7 @@ module JSONAPI
|
|
24
27
|
:top_level_meta_page_count_key,
|
25
28
|
:allow_transactions,
|
26
29
|
:include_backtraces_in_errors,
|
30
|
+
:include_application_backtraces_in_errors,
|
27
31
|
:exception_class_whitelist,
|
28
32
|
:whitelist_all_exceptions,
|
29
33
|
:always_include_to_one_linkage_data,
|
@@ -31,10 +35,12 @@ module JSONAPI
|
|
31
35
|
:cache_formatters,
|
32
36
|
:use_relationship_reflection,
|
33
37
|
:resource_cache,
|
38
|
+
:default_caching,
|
34
39
|
:default_resource_cache_field,
|
35
40
|
:resource_cache_digest_function,
|
36
41
|
:resource_cache_usage_report_function,
|
37
|
-
:default_exclude_links
|
42
|
+
:default_exclude_links,
|
43
|
+
:use_related_resource_records_for_joins
|
38
44
|
|
39
45
|
def initialize
|
40
46
|
#:underscored_key, :camelized_key, :dasherized_key, or custom
|
@@ -47,13 +53,16 @@ module JSONAPI
|
|
47
53
|
self.resource_key_type = :integer
|
48
54
|
|
49
55
|
# optional request features
|
50
|
-
self.
|
56
|
+
self.default_allow_include_to_one = true
|
57
|
+
self.default_allow_include_to_many = true
|
51
58
|
self.allow_sort = true
|
52
59
|
self.allow_filter = true
|
53
60
|
|
54
61
|
self.raise_if_parameters_not_allowed = true
|
55
62
|
|
63
|
+
self.warn_on_route_setup_issues = true
|
56
64
|
self.warn_on_missing_routes = true
|
65
|
+
self.warn_on_performance_issues = true
|
57
66
|
|
58
67
|
# :none, :offset, :paged, or a custom paginator name
|
59
68
|
self.default_paginator = :none
|
@@ -75,8 +84,12 @@ module JSONAPI
|
|
75
84
|
self.use_text_errors = false
|
76
85
|
|
77
86
|
# Whether or not to include exception backtraces in JSONAPI error
|
78
|
-
# responses. Defaults to `false` in
|
79
|
-
self.include_backtraces_in_errors =
|
87
|
+
# responses. Defaults to `false` in anything other than development or test.
|
88
|
+
self.include_backtraces_in_errors = (Rails.env.development? || Rails.env.test?)
|
89
|
+
|
90
|
+
# Whether or not to include exception application backtraces in JSONAPI error
|
91
|
+
# responses. Defaults to `false` in anything other than development or test.
|
92
|
+
self.include_application_backtraces_in_errors = (Rails.env.development? || Rails.env.test?)
|
80
93
|
|
81
94
|
# List of classes that should not be rescued by the operations processor.
|
82
95
|
# For example, if you use Pundit for authorization, you might
|
@@ -98,7 +111,7 @@ module JSONAPI
|
|
98
111
|
|
99
112
|
# The default Operation Processor to use if one is not defined specifically
|
100
113
|
# for a Resource.
|
101
|
-
self.
|
114
|
+
self.default_processor_klass_name = 'JSONAPI::Processor'
|
102
115
|
|
103
116
|
# Allows transactions for creating and updating records
|
104
117
|
# Set this to false if your backend does not support transactions (e.g. Mongodb)
|
@@ -121,6 +134,11 @@ module JSONAPI
|
|
121
134
|
# Rails cache store.
|
122
135
|
self.resource_cache = nil
|
123
136
|
|
137
|
+
# Cache resources by default
|
138
|
+
# Cache resources by default. Individual resources can be excluded from caching by calling:
|
139
|
+
# `caching false`
|
140
|
+
self.default_caching = false
|
141
|
+
|
124
142
|
# Default resource cache field
|
125
143
|
# On Resources with caching enabled, this field will be used to check for out-of-date
|
126
144
|
# cache entries, unless overridden on a specific Resource. Defaults to "updated_at".
|
@@ -141,6 +159,11 @@ module JSONAPI
|
|
141
159
|
# and relationships. Accepts either `:default`, `:none`, or array containing the
|
142
160
|
# specific default links to exclude, which may be `:self` and `:related`.
|
143
161
|
self.default_exclude_links = :none
|
162
|
+
|
163
|
+
# Use a related resource's `records` when performing joins. This setting allows included resources to account for
|
164
|
+
# permission scopes. It can be overridden explicitly per relationship. Furthermore, specifying a `relation_name`
|
165
|
+
# on a relationship will cause this setting to be ignored.
|
166
|
+
self.use_related_resource_records_for_joins = true
|
144
167
|
end
|
145
168
|
|
146
169
|
def cache_formatters=(bool)
|
@@ -208,10 +231,26 @@ module JSONAPI
|
|
208
231
|
end
|
209
232
|
|
210
233
|
def default_processor_klass=(default_processor_klass)
|
234
|
+
ActiveSupport::Deprecation.warn('`default_processor_klass` has been replaced by `default_processor_klass_name`.')
|
211
235
|
@default_processor_klass = default_processor_klass
|
212
236
|
end
|
213
237
|
|
214
|
-
|
238
|
+
def default_processor_klass
|
239
|
+
@default_processor_klass ||= default_processor_klass_name.safe_constantize
|
240
|
+
end
|
241
|
+
|
242
|
+
def default_processor_klass_name=(default_processor_klass_name)
|
243
|
+
@default_processor_klass = nil
|
244
|
+
@default_processor_klass_name = default_processor_klass_name
|
245
|
+
end
|
246
|
+
|
247
|
+
def allow_include=(allow_include)
|
248
|
+
ActiveSupport::Deprecation.warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.')
|
249
|
+
@default_allow_include_to_one = allow_include
|
250
|
+
@default_allow_include_to_many = allow_include
|
251
|
+
end
|
252
|
+
|
253
|
+
attr_writer :allow_sort, :allow_filter, :default_allow_include_to_one, :default_allow_include_to_many
|
215
254
|
|
216
255
|
attr_writer :default_paginator
|
217
256
|
|
@@ -235,6 +274,8 @@ module JSONAPI
|
|
235
274
|
|
236
275
|
attr_writer :include_backtraces_in_errors
|
237
276
|
|
277
|
+
attr_writer :include_application_backtraces_in_errors
|
278
|
+
|
238
279
|
attr_writer :exception_class_whitelist
|
239
280
|
|
240
281
|
attr_writer :whitelist_all_exceptions
|
@@ -245,12 +286,18 @@ module JSONAPI
|
|
245
286
|
|
246
287
|
attr_writer :raise_if_parameters_not_allowed
|
247
288
|
|
289
|
+
attr_writer :warn_on_route_setup_issues
|
290
|
+
|
248
291
|
attr_writer :warn_on_missing_routes
|
249
292
|
|
293
|
+
attr_writer :warn_on_performance_issues
|
294
|
+
|
250
295
|
attr_writer :use_relationship_reflection
|
251
296
|
|
252
297
|
attr_writer :resource_cache
|
253
298
|
|
299
|
+
attr_writer :default_caching
|
300
|
+
|
254
301
|
attr_writer :default_resource_cache_field
|
255
302
|
|
256
303
|
attr_writer :resource_cache_digest_function
|
@@ -258,6 +305,8 @@ module JSONAPI
|
|
258
305
|
attr_writer :resource_cache_usage_report_function
|
259
306
|
|
260
307
|
attr_writer :default_exclude_links
|
308
|
+
|
309
|
+
attr_writer :use_related_resource_records_for_joins
|
261
310
|
end
|
262
311
|
|
263
312
|
class << self
|
data/lib/jsonapi/error.rb
CHANGED
@@ -24,6 +24,33 @@ module JSONAPI
|
|
24
24
|
instance_variables.each {|var| hash[var.to_s.delete('@')] = instance_variable_get(var) unless instance_variable_get(var).nil? }
|
25
25
|
hash
|
26
26
|
end
|
27
|
+
|
28
|
+
def update_with_overrides(error_object_overrides)
|
29
|
+
@title = error_object_overrides[:title] || @title
|
30
|
+
@detail = error_object_overrides[:detail] || @detail
|
31
|
+
@id = error_object_overrides[:id] || @id
|
32
|
+
@href = error_object_overrides[:href] || href
|
33
|
+
|
34
|
+
if error_object_overrides[:code]
|
35
|
+
# :nocov:
|
36
|
+
@code = if JSONAPI.configuration.use_text_errors
|
37
|
+
TEXT_ERRORS[error_object_overrides[:code]]
|
38
|
+
else
|
39
|
+
error_object_overrides[:code]
|
40
|
+
end
|
41
|
+
# :nocov:
|
42
|
+
end
|
43
|
+
|
44
|
+
@source = error_object_overrides[:source] || @source
|
45
|
+
@links = error_object_overrides[:links] || @links
|
46
|
+
|
47
|
+
if error_object_overrides[:status]
|
48
|
+
# :nocov:
|
49
|
+
@status = Rack::Utils::SYMBOL_TO_STATUS_CODE[error_object_overrides[:status]].to_s
|
50
|
+
# :nocov:
|
51
|
+
end
|
52
|
+
@meta = error_object_overrides[:meta] || @meta
|
53
|
+
end
|
27
54
|
end
|
28
55
|
|
29
56
|
class Warning
|
data/lib/jsonapi/error_codes.rb
CHANGED
@@ -20,6 +20,7 @@ module JSONAPI
|
|
20
20
|
INVALID_FILTERS_SYNTAX = '120'
|
21
21
|
SAVE_FAILED = '121'
|
22
22
|
INVALID_DATA_FORMAT = '122'
|
23
|
+
INVALID_RELATIONSHIP = '123'
|
23
24
|
BAD_REQUEST = '400'
|
24
25
|
FORBIDDEN = '403'
|
25
26
|
RECORD_NOT_FOUND = '404'
|
@@ -50,6 +51,7 @@ module JSONAPI
|
|
50
51
|
INVALID_FILTERS_SYNTAX => 'INVALID_FILTERS_SYNTAX',
|
51
52
|
SAVE_FAILED => 'SAVE_FAILED',
|
52
53
|
INVALID_DATA_FORMAT => 'INVALID_DATA_FORMAT',
|
54
|
+
INVALID_RELATIONSHIP => 'INVALID_RELATIONSHIP',
|
53
55
|
FORBIDDEN => 'FORBIDDEN',
|
54
56
|
RECORD_NOT_FOUND => 'RECORD_NOT_FOUND',
|
55
57
|
NOT_ACCEPTABLE => 'NOT_ACCEPTABLE',
|
data/lib/jsonapi/exceptions.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
module Exceptions
|
3
3
|
class Error < RuntimeError
|
4
|
-
|
4
|
+
attr_reader :error_object_overrides
|
5
5
|
|
6
6
|
def initialize(error_object_overrides = {})
|
7
7
|
@error_object_overrides = error_object_overrides
|
@@ -18,6 +18,22 @@ module JSONAPI
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
class Errors < Error
|
22
|
+
def initialize(errors, error_object_overrides = {})
|
23
|
+
@errors = errors
|
24
|
+
|
25
|
+
@errors.each do |error|
|
26
|
+
error.update_with_overrides(error_object_overrides)
|
27
|
+
end
|
28
|
+
|
29
|
+
super(error_object_overrides)
|
30
|
+
end
|
31
|
+
|
32
|
+
def errors
|
33
|
+
@errors
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
21
37
|
class InternalServerError < Error
|
22
38
|
attr_accessor :exception
|
23
39
|
|
@@ -33,6 +49,12 @@ module JSONAPI
|
|
33
49
|
meta[:backtrace] = exception.backtrace
|
34
50
|
end
|
35
51
|
|
52
|
+
if JSONAPI.configuration.include_application_backtraces_in_errors
|
53
|
+
meta ||= Hash.new
|
54
|
+
meta[:exception] ||= exception.message
|
55
|
+
meta[:application_backtrace] = exception.backtrace.select{|line| line =~ /#{Rails.root}/}
|
56
|
+
end
|
57
|
+
|
36
58
|
[create_error_object(code: JSONAPI::INTERNAL_SERVER_ERROR,
|
37
59
|
status: :internal_server_error,
|
38
60
|
title: I18n.t('jsonapi-resources.exceptions.internal_server_error.title',
|
@@ -119,49 +141,30 @@ module JSONAPI
|
|
119
141
|
end
|
120
142
|
end
|
121
143
|
|
122
|
-
|
123
|
-
class HasManyRelationExists < Error
|
124
|
-
attr_accessor :id
|
125
|
-
|
126
|
-
def initialize(id, error_object_overrides = {})
|
127
|
-
@id = id
|
128
|
-
super(error_object_overrides)
|
129
|
-
end
|
130
|
-
|
131
|
-
def errors
|
132
|
-
[create_error_object(code: JSONAPI::RELATION_EXISTS,
|
133
|
-
status: :bad_request,
|
134
|
-
title: I18n.translate('jsonapi-resources.exceptions.has_many_relation.title',
|
135
|
-
default: 'Relation exists'),
|
136
|
-
detail: I18n.translate('jsonapi-resources.exceptions.has_many_relation.detail',
|
137
|
-
default: "The relation to #{id} already exists.",
|
138
|
-
id: id))]
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
144
|
class BadRequest < Error
|
143
|
-
def initialize(exception)
|
145
|
+
def initialize(exception, error_object_overrides = {})
|
144
146
|
@exception = exception
|
147
|
+
super(error_object_overrides)
|
145
148
|
end
|
146
149
|
|
147
150
|
def errors
|
148
|
-
[
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
[create_error_object(code: JSONAPI::BAD_REQUEST,
|
152
|
+
status: :bad_request,
|
153
|
+
title: I18n.translate('jsonapi-resources.exceptions.bad_request.title',
|
154
|
+
default: 'Bad Request'),
|
155
|
+
detail: I18n.translate('jsonapi-resources.exceptions.bad_request.detail',
|
156
|
+
default: @exception))]
|
154
157
|
end
|
155
158
|
end
|
156
159
|
|
157
160
|
class InvalidRequestFormat < Error
|
158
161
|
def errors
|
159
|
-
[
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
162
|
+
[create_error_object(code: JSONAPI::BAD_REQUEST,
|
163
|
+
status: :bad_request,
|
164
|
+
title: I18n.translate('jsonapi-resources.exceptions.invalid_request_format.title',
|
165
|
+
default: 'Bad Request'),
|
166
|
+
detail: I18n.translate('jsonapi-resources.exceptions.invalid_request_format.detail',
|
167
|
+
default: 'Request must be a hash'))]
|
165
168
|
end
|
166
169
|
end
|
167
170
|
|
@@ -324,6 +327,26 @@ module JSONAPI
|
|
324
327
|
end
|
325
328
|
end
|
326
329
|
|
330
|
+
class InvalidRelationship < Error
|
331
|
+
attr_accessor :relationship_name, :type
|
332
|
+
|
333
|
+
def initialize(type, relationship_name, error_object_overrides = {})
|
334
|
+
@relationship_name = relationship_name
|
335
|
+
@type = type
|
336
|
+
super(error_object_overrides)
|
337
|
+
end
|
338
|
+
|
339
|
+
def errors
|
340
|
+
[create_error_object(code: JSONAPI::INVALID_RELATIONSHIP,
|
341
|
+
status: :bad_request,
|
342
|
+
title: I18n.translate('jsonapi-resources.exceptions.invalid_relationship.title',
|
343
|
+
default: 'Invalid relationship'),
|
344
|
+
detail: I18n.translate('jsonapi-resources.exceptions.invalid_relationship.detail',
|
345
|
+
default: "#{relationship_name} is not a valid field for #{type}.",
|
346
|
+
relationship_name: relationship_name, type: type))]
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
327
350
|
class InvalidInclude < Error
|
328
351
|
attr_accessor :relationship, :resource
|
329
352
|
|
@@ -339,7 +362,7 @@ module JSONAPI
|
|
339
362
|
title: I18n.translate('jsonapi-resources.exceptions.invalid_include.title',
|
340
363
|
default: 'Invalid field'),
|
341
364
|
detail: I18n.translate('jsonapi-resources.exceptions.invalid_include.detail',
|
342
|
-
default: "#{relationship} is not a valid relationship of #{resource}",
|
365
|
+
default: "#{relationship} is not a valid includable relationship of #{resource}",
|
343
366
|
relationship: relationship, resource: resource))]
|
344
367
|
end
|
345
368
|
end
|
@@ -374,11 +397,11 @@ module JSONAPI
|
|
374
397
|
|
375
398
|
def errors
|
376
399
|
[create_error_object(code: JSONAPI::PARAM_NOT_ALLOWED,
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
400
|
+
status: :bad_request,
|
401
|
+
title: I18n.translate('jsonapi-resources.exceptions.parameter_not_allowed.title',
|
402
|
+
default: 'Param not allowed'),
|
403
|
+
detail: I18n.translate('jsonapi-resources.exceptions.parameters_not_allowed.detail',
|
404
|
+
default: "#{param} is not allowed.", param: param))]
|
382
405
|
end
|
383
406
|
end
|
384
407
|
|
data/lib/jsonapi/formatter.rb
CHANGED
@@ -108,7 +108,7 @@ end
|
|
108
108
|
|
109
109
|
class DasherizedKeyFormatter < JSONAPI::KeyFormatter
|
110
110
|
class << self
|
111
|
-
def format(
|
111
|
+
def format(_key)
|
112
112
|
super.underscore.dasherize
|
113
113
|
end
|
114
114
|
|
@@ -146,7 +146,7 @@ end
|
|
146
146
|
|
147
147
|
class CamelizedRouteFormatter < JSONAPI::RouteFormatter
|
148
148
|
class << self
|
149
|
-
def format(
|
149
|
+
def format(_route)
|
150
150
|
super.camelize(:lower)
|
151
151
|
end
|
152
152
|
|
@@ -158,7 +158,7 @@ end
|
|
158
158
|
|
159
159
|
class DasherizedRouteFormatter < JSONAPI::RouteFormatter
|
160
160
|
class << self
|
161
|
-
def format(
|
161
|
+
def format(_route)
|
162
162
|
super.dasherize
|
163
163
|
end
|
164
164
|
|