jsonapi-resources 0.7.1.beta1 → 0.7.1.beta2
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/README.md +248 -74
- data/lib/jsonapi-resources.rb +5 -3
- data/lib/jsonapi/acts_as_resource_controller.rb +77 -14
- data/lib/jsonapi/configuration.rb +77 -16
- data/lib/jsonapi/error.rb +12 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +29 -9
- data/lib/jsonapi/formatter.rb +29 -4
- data/lib/jsonapi/link_builder.rb +18 -18
- data/lib/jsonapi/mime_types.rb +25 -6
- data/lib/jsonapi/naive_cache.rb +30 -0
- data/lib/jsonapi/operation.rb +10 -342
- data/lib/jsonapi/operation_dispatcher.rb +87 -0
- data/lib/jsonapi/operation_result.rb +2 -1
- data/lib/jsonapi/paginator.rb +6 -2
- data/lib/jsonapi/processor.rb +283 -0
- data/lib/jsonapi/relationship.rb +6 -4
- data/lib/jsonapi/{request.rb → request_parser.rb} +46 -35
- data/lib/jsonapi/resource.rb +88 -13
- data/lib/jsonapi/resource_controller.rb +2 -14
- data/lib/jsonapi/resource_controller_metal.rb +17 -0
- data/lib/jsonapi/resource_serializer.rb +62 -47
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +13 -2
- data/lib/jsonapi/routing_ext.rb +49 -11
- metadata +37 -129
- data/.gitignore +0 -22
- data/.travis.yml +0 -9
- data/Gemfile +0 -23
- data/Rakefile +0 -20
- data/jsonapi-resources.gemspec +0 -29
- data/lib/jsonapi/active_record_operations_processor.rb +0 -35
- data/lib/jsonapi/operations_processor.rb +0 -120
- data/locales/en.yml +0 -80
- data/test/config/database.yml +0 -5
- data/test/controllers/controller_test.rb +0 -3312
- data/test/fixtures/active_record.rb +0 -1486
- data/test/fixtures/author_details.yml +0 -9
- data/test/fixtures/book_authors.yml +0 -3
- data/test/fixtures/book_comments.yml +0 -12
- data/test/fixtures/books.yml +0 -7
- data/test/fixtures/categories.yml +0 -35
- data/test/fixtures/comments.yml +0 -21
- data/test/fixtures/comments_tags.yml +0 -20
- data/test/fixtures/companies.yml +0 -4
- data/test/fixtures/craters.yml +0 -9
- data/test/fixtures/customers.yml +0 -11
- data/test/fixtures/documents.yml +0 -3
- data/test/fixtures/expense_entries.yml +0 -13
- data/test/fixtures/facts.yml +0 -11
- data/test/fixtures/hair_cuts.yml +0 -3
- data/test/fixtures/iso_currencies.yml +0 -17
- data/test/fixtures/line_items.yml +0 -37
- data/test/fixtures/makes.yml +0 -2
- data/test/fixtures/moons.yml +0 -6
- data/test/fixtures/numeros_telefone.yml +0 -3
- data/test/fixtures/order_flags.yml +0 -7
- data/test/fixtures/people.yml +0 -31
- data/test/fixtures/pictures.yml +0 -15
- data/test/fixtures/planet_types.yml +0 -19
- data/test/fixtures/planets.yml +0 -47
- data/test/fixtures/posts.yml +0 -102
- data/test/fixtures/posts_tags.yml +0 -59
- data/test/fixtures/preferences.yml +0 -14
- data/test/fixtures/products.yml +0 -3
- data/test/fixtures/purchase_orders.yml +0 -23
- data/test/fixtures/sections.yml +0 -8
- data/test/fixtures/tags.yml +0 -39
- data/test/fixtures/vehicles.yml +0 -17
- data/test/fixtures/web_pages.yml +0 -3
- data/test/helpers/assertions.rb +0 -13
- data/test/helpers/functional_helpers.rb +0 -59
- data/test/helpers/value_matchers.rb +0 -60
- data/test/helpers/value_matchers_test.rb +0 -40
- data/test/integration/requests/namespaced_model_test.rb +0 -13
- data/test/integration/requests/request_test.rb +0 -932
- data/test/integration/routes/routes_test.rb +0 -218
- data/test/integration/sti_fields_test.rb +0 -18
- data/test/lib/generators/jsonapi/controller_generator_test.rb +0 -25
- data/test/lib/generators/jsonapi/resource_generator_test.rb +0 -30
- data/test/test_helper.rb +0 -342
- data/test/unit/formatters/dasherized_key_formatter_test.rb +0 -8
- data/test/unit/jsonapi_request/jsonapi_request_test.rb +0 -199
- data/test/unit/operation/operations_processor_test.rb +0 -528
- data/test/unit/pagination/offset_paginator_test.rb +0 -245
- data/test/unit/pagination/paged_paginator_test.rb +0 -242
- data/test/unit/resource/resource_test.rb +0 -560
- data/test/unit/serializer/include_directives_test.rb +0 -113
- data/test/unit/serializer/link_builder_test.rb +0 -244
- data/test/unit/serializer/polymorphic_serializer_test.rb +0 -383
- data/test/unit/serializer/response_document_test.rb +0 -61
- data/test/unit/serializer/serializer_test.rb +0 -1939
data/lib/jsonapi/formatter.rb
CHANGED
@@ -9,9 +9,12 @@ module JSONAPI
|
|
9
9
|
arg
|
10
10
|
end
|
11
11
|
|
12
|
+
def cached
|
13
|
+
return FormatterWrapperCache.new(self)
|
14
|
+
end
|
15
|
+
|
12
16
|
def formatter_for(format)
|
13
|
-
|
14
|
-
formatter_class_name.safe_constantize
|
17
|
+
"#{format.to_s.camelize}Formatter".safe_constantize
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
@@ -51,11 +54,33 @@ module JSONAPI
|
|
51
54
|
end
|
52
55
|
|
53
56
|
def value_formatter_for(type)
|
54
|
-
|
55
|
-
formatter_for(formatter_name)
|
57
|
+
"#{type.to_s.camelize}ValueFormatter".safe_constantize
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
61
|
+
|
62
|
+
# Warning: Not thread-safe. Wrap in ThreadLocalVar as needed.
|
63
|
+
class FormatterWrapperCache
|
64
|
+
attr_reader :formatter_klass
|
65
|
+
|
66
|
+
def initialize(formatter_klass)
|
67
|
+
@formatter_klass = formatter_klass
|
68
|
+
@format_cache = NaiveCache.new{|arg| formatter_klass.format(arg) }
|
69
|
+
@unformat_cache = NaiveCache.new{|arg| formatter_klass.unformat(arg) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def format(arg)
|
73
|
+
@format_cache.get(arg)
|
74
|
+
end
|
75
|
+
|
76
|
+
def unformat(arg)
|
77
|
+
@unformat_cache.get(arg)
|
78
|
+
end
|
79
|
+
|
80
|
+
def cached
|
81
|
+
self
|
82
|
+
end
|
83
|
+
end
|
59
84
|
end
|
60
85
|
|
61
86
|
class UnderscoredKeyFormatter < JSONAPI::KeyFormatter
|
data/lib/jsonapi/link_builder.rb
CHANGED
@@ -2,21 +2,24 @@ module JSONAPI
|
|
2
2
|
class LinkBuilder
|
3
3
|
attr_reader :base_url,
|
4
4
|
:primary_resource_klass,
|
5
|
-
:route_formatter
|
5
|
+
:route_formatter,
|
6
|
+
:engine_name
|
6
7
|
|
7
8
|
def initialize(config = {})
|
8
9
|
@base_url = config[:base_url]
|
9
10
|
@primary_resource_klass = config[:primary_resource_klass]
|
10
11
|
@route_formatter = config[:route_formatter]
|
11
|
-
@
|
12
|
-
end
|
12
|
+
@engine_name = build_engine_name
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
# Warning: These make LinkBuilder non-thread-safe. That's not a problem with the
|
15
|
+
# request-specific way it's currently used, though.
|
16
|
+
@resources_path_cache = JSONAPI::NaiveCache.new do |source_klass|
|
17
|
+
formatted_module_path_from_class(source_klass) + format_route(source_klass._type.to_s)
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
19
|
-
|
21
|
+
def engine?
|
22
|
+
!!@engine_name
|
20
23
|
end
|
21
24
|
|
22
25
|
def primary_resources_url
|
@@ -96,14 +99,14 @@ module JSONAPI
|
|
96
99
|
end
|
97
100
|
|
98
101
|
def format_route(route)
|
99
|
-
route_formatter.format(route
|
102
|
+
route_formatter.format(route)
|
100
103
|
end
|
101
104
|
|
102
105
|
def formatted_module_path_from_class(klass)
|
103
106
|
scopes = module_scopes_from_class(klass)
|
104
107
|
|
105
108
|
unless scopes.empty?
|
106
|
-
"/#{ scopes.map(
|
109
|
+
"/#{ scopes.map{ |scope| format_route(scope.to_s.underscore) }.join('/') }/"
|
107
110
|
else
|
108
111
|
"/"
|
109
112
|
end
|
@@ -113,11 +116,12 @@ module JSONAPI
|
|
113
116
|
klass.name.to_s.split("::")[0...-1]
|
114
117
|
end
|
115
118
|
|
119
|
+
def regular_resources_path(source_klass)
|
120
|
+
@resources_path_cache.get(source_klass)
|
121
|
+
end
|
122
|
+
|
116
123
|
def regular_primary_resources_path
|
117
|
-
|
118
|
-
formatted_module_path_from_class(primary_resource_klass),
|
119
|
-
format_route(primary_resource_klass._type.to_s),
|
120
|
-
].join
|
124
|
+
regular_resources_path(primary_resource_klass)
|
121
125
|
end
|
122
126
|
|
123
127
|
def regular_primary_resources_url
|
@@ -125,11 +129,7 @@ module JSONAPI
|
|
125
129
|
end
|
126
130
|
|
127
131
|
def regular_resource_path(source)
|
128
|
-
|
129
|
-
formatted_module_path_from_class(source.class),
|
130
|
-
format_route(source.class._type.to_s),
|
131
|
-
"/#{ source.id }",
|
132
|
-
].join
|
132
|
+
"#{regular_resources_path(source.class)}/#{source.id}"
|
133
133
|
end
|
134
134
|
|
135
135
|
def regular_resource_url(source)
|
data/lib/jsonapi/mime_types.rb
CHANGED
@@ -1,11 +1,30 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
MEDIA_TYPE = 'application/vnd.api+json'
|
3
|
-
end
|
4
3
|
|
5
|
-
|
4
|
+
module MimeTypes
|
5
|
+
def self.install
|
6
|
+
Mime::Type.register JSONAPI::MEDIA_TYPE, :api_json
|
7
|
+
|
8
|
+
# :nocov:
|
9
|
+
if Rails::VERSION::MAJOR >= 5
|
10
|
+
parsers = ActionDispatch::Request.parameter_parsers.merge(
|
11
|
+
Mime::Type.lookup(JSONAPI::MEDIA_TYPE).symbol => parser
|
12
|
+
)
|
13
|
+
ActionDispatch::Request.parameter_parsers = parsers
|
14
|
+
else
|
15
|
+
ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime::Type.lookup(JSONAPI::MEDIA_TYPE)] = parser
|
16
|
+
end
|
17
|
+
# :nocov:
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parser
|
21
|
+
lambda do |body|
|
22
|
+
data = JSON.parse(body)
|
23
|
+
data = {:_json => data} unless data.is_a?(Hash)
|
24
|
+
data.with_indifferent_access
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
6
28
|
|
7
|
-
|
8
|
-
data = JSON.parse(body)
|
9
|
-
data = {:_json => data} unless data.is_a?(Hash)
|
10
|
-
data.with_indifferent_access
|
29
|
+
MimeTypes.install
|
11
30
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
|
3
|
+
# Cache which memoizes the given block.
|
4
|
+
#
|
5
|
+
# It's "naive" because it clears the least-recently-inserted cache entry
|
6
|
+
# rather than the least-recently-used. This makes lookups faster but cache
|
7
|
+
# misses more frequent after cleanups. Therefore you the best time to use
|
8
|
+
# this cache is when you expect only a small number of unique lookup keys, so
|
9
|
+
# that the cache never has to clear.
|
10
|
+
#
|
11
|
+
# Also, it's not thread safe (although jsonapi-resources is careful to only
|
12
|
+
# use it in a thread safe way).
|
13
|
+
class NaiveCache
|
14
|
+
def initialize(cap = 10000, &calculator)
|
15
|
+
@cap = cap
|
16
|
+
@data = {}
|
17
|
+
@calculator = calculator
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(key)
|
21
|
+
found = true
|
22
|
+
value = @data.fetch(key) { found = false }
|
23
|
+
return value if found
|
24
|
+
value = @calculator.call(key)
|
25
|
+
@data[key] = value
|
26
|
+
@data.shift if @data.length > @cap
|
27
|
+
return value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/jsonapi/operation.rb
CHANGED
@@ -1,356 +1,24 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
class Operation
|
3
|
-
attr_reader :resource_klass, :
|
3
|
+
attr_reader :resource_klass, :operation_type, :options
|
4
4
|
|
5
|
-
def initialize(resource_klass, options
|
6
|
-
@
|
5
|
+
def initialize(operation_type, resource_klass, options)
|
6
|
+
@operation_type = operation_type
|
7
7
|
@resource_klass = resource_klass
|
8
8
|
@options = options
|
9
|
-
@transactional = true
|
10
9
|
end
|
11
10
|
|
12
|
-
def
|
11
|
+
def transactional?
|
12
|
+
JSONAPI::Processor._processor_from_resource_type(resource_klass).transactional_operation_type?(operation_type)
|
13
13
|
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class FindOperation < Operation
|
17
|
-
attr_reader :filters, :include_directives, :sort_criteria, :paginator
|
18
|
-
|
19
|
-
def initialize(resource_klass, options = {})
|
20
|
-
super(resource_klass, options)
|
21
|
-
@filters = options[:filters]
|
22
|
-
@include_directives = options[:include_directives]
|
23
|
-
@sort_criteria = options.fetch(:sort_criteria, [])
|
24
|
-
@paginator = options[:paginator]
|
25
|
-
@transactional = false
|
26
|
-
end
|
27
|
-
|
28
|
-
def record_count
|
29
|
-
@_record_count ||= @resource_klass.find_count(@resource_klass.verify_filters(@filters, @context),
|
30
|
-
context: @context,
|
31
|
-
include_directives: @include_directives)
|
32
|
-
end
|
33
|
-
|
34
|
-
def pagination_params
|
35
|
-
if @paginator && JSONAPI.configuration.top_level_links_include_pagination
|
36
|
-
options = {}
|
37
|
-
options[:record_count] = record_count if @paginator.class.requires_record_count
|
38
|
-
return @paginator.links_page_params(options)
|
39
|
-
else
|
40
|
-
return {}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def apply
|
45
|
-
resource_records = @resource_klass.find(@resource_klass.verify_filters(@filters, @context),
|
46
|
-
context: @context,
|
47
|
-
include_directives: @include_directives,
|
48
|
-
sort_criteria: @sort_criteria,
|
49
|
-
paginator: @paginator)
|
50
|
-
|
51
|
-
options = {}
|
52
|
-
if JSONAPI.configuration.top_level_links_include_pagination
|
53
|
-
options[:pagination_params] = pagination_params
|
54
|
-
end
|
55
|
-
|
56
|
-
if JSONAPI.configuration.top_level_meta_include_record_count
|
57
|
-
options[:record_count] = record_count
|
58
|
-
end
|
59
|
-
|
60
|
-
return JSONAPI::ResourcesOperationResult.new(:ok,
|
61
|
-
resource_records,
|
62
|
-
options)
|
63
|
-
|
64
|
-
rescue JSONAPI::Exceptions::Error => e
|
65
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class ShowOperation < Operation
|
70
|
-
attr_reader :id, :include_directives
|
71
|
-
|
72
|
-
def initialize(resource_klass, options = {})
|
73
|
-
super(resource_klass, options)
|
74
|
-
@id = options.fetch(:id)
|
75
|
-
@include_directives = options[:include_directives]
|
76
|
-
@transactional = false
|
77
|
-
end
|
78
|
-
|
79
|
-
def apply
|
80
|
-
key = @resource_klass.verify_key(@id, @context)
|
81
|
-
|
82
|
-
resource_record = @resource_klass.find_by_key(key,
|
83
|
-
context: @context,
|
84
|
-
include_directives: @include_directives)
|
85
|
-
|
86
|
-
return JSONAPI::ResourceOperationResult.new(:ok, resource_record)
|
87
|
-
|
88
|
-
rescue JSONAPI::Exceptions::Error => e
|
89
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
class ShowRelationshipOperation < Operation
|
94
|
-
attr_reader :parent_key, :relationship_type
|
95
|
-
|
96
|
-
def initialize(resource_klass, options = {})
|
97
|
-
super(resource_klass, options)
|
98
|
-
@parent_key = options.fetch(:parent_key)
|
99
|
-
@relationship_type = options.fetch(:relationship_type)
|
100
|
-
@transactional = false
|
101
|
-
end
|
102
|
-
|
103
|
-
def apply
|
104
|
-
parent_resource = resource_klass.find_by_key(@parent_key, context: @context)
|
105
|
-
|
106
|
-
return JSONAPI::LinksObjectOperationResult.new(:ok,
|
107
|
-
parent_resource,
|
108
|
-
resource_klass._relationship(@relationship_type))
|
109
|
-
|
110
|
-
rescue JSONAPI::Exceptions::Error => e
|
111
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class ShowRelatedResourceOperation < Operation
|
116
|
-
attr_reader :source_klass, :source_id, :relationship_type
|
117
|
-
|
118
|
-
def initialize(resource_klass, options = {})
|
119
|
-
super(resource_klass, options)
|
120
|
-
@source_klass = options.fetch(:source_klass)
|
121
|
-
@source_id = options.fetch(:source_id)
|
122
|
-
@relationship_type = options.fetch(:relationship_type)
|
123
|
-
@transactional = false
|
124
|
-
end
|
125
|
-
|
126
|
-
def apply
|
127
|
-
source_resource = @source_klass.find_by_key(@source_id, context: @context)
|
128
|
-
|
129
|
-
related_resource = source_resource.public_send(@relationship_type)
|
130
|
-
|
131
|
-
return JSONAPI::ResourceOperationResult.new(:ok, related_resource)
|
132
|
-
|
133
|
-
rescue JSONAPI::Exceptions::Error => e
|
134
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
class ShowRelatedResourcesOperation < Operation
|
139
|
-
attr_reader :source_klass, :source_id, :relationship_type, :filters, :sort_criteria, :paginator
|
140
|
-
|
141
|
-
def initialize(resource_klass, options = {})
|
142
|
-
super(resource_klass, options)
|
143
|
-
@source_klass = options.fetch(:source_klass)
|
144
|
-
@source_id = options.fetch(:source_id)
|
145
|
-
@relationship_type = options.fetch(:relationship_type)
|
146
|
-
@filters = options[:filters]
|
147
|
-
@sort_criteria = options[:sort_criteria]
|
148
|
-
@paginator = options[:paginator]
|
149
|
-
@transactional = false
|
150
|
-
end
|
151
|
-
|
152
|
-
def record_count
|
153
|
-
@_record_count ||= records.count(:all)
|
154
|
-
end
|
155
|
-
|
156
|
-
def source_resource
|
157
|
-
@_source_resource ||= @source_klass.find_by_key(@source_id, context: @context)
|
158
|
-
end
|
159
|
-
|
160
|
-
def records
|
161
|
-
related_resource_records = source_resource.public_send("records_for_" + @relationship_type)
|
162
|
-
@resource_klass.filter_records(@filters, @options, related_resource_records)
|
163
|
-
end
|
164
|
-
|
165
|
-
def pagination_params
|
166
|
-
if @paginator && JSONAPI.configuration.top_level_links_include_pagination
|
167
|
-
options = {}
|
168
|
-
options[:record_count] = record_count if @paginator.class.requires_record_count
|
169
|
-
@paginator.links_page_params(options)
|
170
|
-
else
|
171
|
-
{}
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def options
|
176
|
-
opts = {}
|
177
|
-
opts.merge!(pagination_params: pagination_params) if JSONAPI.configuration.top_level_links_include_pagination
|
178
|
-
opts.merge!(record_count: record_count) if JSONAPI.configuration.top_level_meta_include_record_count
|
179
|
-
opts
|
180
|
-
end
|
181
|
-
|
182
|
-
def apply
|
183
|
-
related_resource = source_resource.public_send(@relationship_type,
|
184
|
-
filters: @filters,
|
185
|
-
sort_criteria: @sort_criteria,
|
186
|
-
paginator: @paginator)
|
187
|
-
|
188
|
-
return JSONAPI::RelatedResourcesOperationResult.new(:ok, source_resource, @relationship_type, related_resource, options)
|
189
|
-
|
190
|
-
rescue JSONAPI::Exceptions::Error => e
|
191
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
192
|
-
end
|
193
|
-
end
|
194
14
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
def initialize(resource_klass, options = {})
|
199
|
-
super(resource_klass, options)
|
200
|
-
@data = options.fetch(:data)
|
201
|
-
end
|
202
|
-
|
203
|
-
def apply
|
204
|
-
resource = @resource_klass.create(@context)
|
205
|
-
result = resource.replace_fields(@data)
|
206
|
-
|
207
|
-
return JSONAPI::ResourceOperationResult.new((result == :completed ? :created : :accepted), resource)
|
208
|
-
|
209
|
-
rescue JSONAPI::Exceptions::Error => e
|
210
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
class RemoveResourceOperation < Operation
|
215
|
-
attr_reader :resource_id
|
216
|
-
def initialize(resource_klass, options = {})
|
217
|
-
super(resource_klass, options)
|
218
|
-
@resource_id = options.fetch(:resource_id)
|
219
|
-
end
|
220
|
-
|
221
|
-
def apply
|
222
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
223
|
-
result = resource.remove
|
224
|
-
|
225
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
226
|
-
|
227
|
-
rescue JSONAPI::Exceptions::Error => e
|
228
|
-
return JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
class ReplaceFieldsOperation < Operation
|
233
|
-
attr_reader :data, :resource_id
|
234
|
-
|
235
|
-
def initialize(resource_klass, options = {})
|
236
|
-
super(resource_klass, options)
|
237
|
-
@resource_id = options.fetch(:resource_id)
|
238
|
-
@data = options.fetch(:data)
|
239
|
-
end
|
240
|
-
|
241
|
-
def apply
|
242
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
243
|
-
result = resource.replace_fields(data)
|
244
|
-
|
245
|
-
return JSONAPI::ResourceOperationResult.new(result == :completed ? :ok : :accepted, resource)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
class ReplaceToOneRelationshipOperation < Operation
|
250
|
-
attr_reader :resource_id, :relationship_type, :key_value
|
251
|
-
|
252
|
-
def initialize(resource_klass, options = {})
|
253
|
-
super(resource_klass, options)
|
254
|
-
@resource_id = options.fetch(:resource_id)
|
255
|
-
@key_value = options.fetch(:key_value)
|
256
|
-
@relationship_type = options.fetch(:relationship_type).to_sym
|
257
|
-
end
|
258
|
-
|
259
|
-
def apply
|
260
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
261
|
-
result = resource.replace_to_one_link(@relationship_type, @key_value)
|
262
|
-
|
263
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
class ReplacePolymorphicToOneRelationshipOperation < Operation
|
268
|
-
attr_reader :resource_id, :relationship_type, :key_value, :key_type
|
269
|
-
|
270
|
-
def initialize(resource_klass, options = {})
|
271
|
-
super(resource_klass, options)
|
272
|
-
@resource_id = options.fetch(:resource_id)
|
273
|
-
@key_value = options.fetch(:key_value)
|
274
|
-
@key_type = options.fetch(:key_type)
|
275
|
-
@relationship_type = options.fetch(:relationship_type).to_sym
|
15
|
+
def process
|
16
|
+
processor.process
|
276
17
|
end
|
277
18
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
class CreateToManyRelationshipOperation < Operation
|
287
|
-
attr_reader :resource_id, :relationship_type, :data
|
288
|
-
|
289
|
-
def initialize(resource_klass, options)
|
290
|
-
super(resource_klass, options)
|
291
|
-
@resource_id = options.fetch(:resource_id)
|
292
|
-
@data = options.fetch(:data)
|
293
|
-
@relationship_type = options.fetch(:relationship_type).to_sym
|
294
|
-
end
|
295
|
-
|
296
|
-
def apply
|
297
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
298
|
-
result = resource.create_to_many_links(@relationship_type, @data)
|
299
|
-
|
300
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
class ReplaceToManyRelationshipOperation < Operation
|
305
|
-
attr_reader :resource_id, :relationship_type, :data
|
306
|
-
|
307
|
-
def initialize(resource_klass, options)
|
308
|
-
super(resource_klass, options)
|
309
|
-
@resource_id = options.fetch(:resource_id)
|
310
|
-
@data = options.fetch(:data)
|
311
|
-
@relationship_type = options.fetch(:relationship_type).to_sym
|
312
|
-
end
|
313
|
-
|
314
|
-
def apply
|
315
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
316
|
-
result = resource.replace_to_many_links(@relationship_type, @data)
|
317
|
-
|
318
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
class RemoveToManyRelationshipOperation < Operation
|
323
|
-
attr_reader :resource_id, :relationship_type, :associated_key
|
324
|
-
|
325
|
-
def initialize(resource_klass, options)
|
326
|
-
super(resource_klass, options)
|
327
|
-
@resource_id = options.fetch(:resource_id)
|
328
|
-
@associated_key = options.fetch(:associated_key)
|
329
|
-
@relationship_type = options.fetch(:relationship_type).to_sym
|
330
|
-
end
|
331
|
-
|
332
|
-
def apply
|
333
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
334
|
-
result = resource.remove_to_many_link(@relationship_type, @associated_key)
|
335
|
-
|
336
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
class RemoveToOneRelationshipOperation < Operation
|
341
|
-
attr_reader :resource_id, :relationship_type
|
342
|
-
|
343
|
-
def initialize(resource_klass, options)
|
344
|
-
super(resource_klass, options)
|
345
|
-
@resource_id = options.fetch(:resource_id)
|
346
|
-
@relationship_type = options.fetch(:relationship_type).to_sym
|
347
|
-
end
|
348
|
-
|
349
|
-
def apply
|
350
|
-
resource = @resource_klass.find_by_key(@resource_id, context: @context)
|
351
|
-
result = resource.remove_to_one_link(@relationship_type)
|
352
|
-
|
353
|
-
return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted)
|
19
|
+
private
|
20
|
+
def processor
|
21
|
+
JSONAPI::Processor.processor_instance_for(resource_klass, operation_type, options)
|
354
22
|
end
|
355
23
|
end
|
356
24
|
end
|