jsonapi-resources 0.7.1.beta1 → 0.7.1.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|