jsonapi-resources 0.9.12 → 0.10.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- 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-resources.rb +8 -3
- data/lib/jsonapi/active_relation_resource_finder.rb +640 -0
- data/lib/jsonapi/active_relation_resource_finder/join_tree.rb +126 -0
- data/lib/jsonapi/acts_as_resource_controller.rb +121 -106
- data/lib/jsonapi/{cached_resource_fragment.rb → cached_response_fragment.rb} +13 -30
- data/lib/jsonapi/compiled_json.rb +11 -1
- data/lib/jsonapi/configuration.rb +44 -18
- data/lib/jsonapi/error.rb +27 -0
- data/lib/jsonapi/exceptions.rb +43 -40
- data/lib/jsonapi/formatter.rb +3 -3
- data/lib/jsonapi/include_directives.rb +2 -45
- data/lib/jsonapi/link_builder.rb +87 -80
- data/lib/jsonapi/operation.rb +16 -5
- data/lib/jsonapi/operation_result.rb +74 -16
- data/lib/jsonapi/processor.rb +233 -112
- data/lib/jsonapi/relationship.rb +77 -53
- data/lib/jsonapi/request_parser.rb +378 -423
- data/lib/jsonapi/resource.rb +224 -524
- data/lib/jsonapi/resource_controller_metal.rb +2 -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 +133 -301
- data/lib/jsonapi/resource_set.rb +108 -0
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +100 -88
- data/lib/jsonapi/routing_ext.rb +21 -43
- metadata +29 -45
- 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,108 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
# Contains a hash of resource types which contain a hash of resources, relationships and primary status keyed by
|
3
|
+
# resource id.
|
4
|
+
class ResourceSet
|
5
|
+
|
6
|
+
attr_reader :resource_klasses, :populated
|
7
|
+
|
8
|
+
def initialize(resource_id_tree)
|
9
|
+
@populated = false
|
10
|
+
@resource_klasses = flatten_resource_id_tree(resource_id_tree)
|
11
|
+
end
|
12
|
+
|
13
|
+
def populate!(serializer, context, find_options)
|
14
|
+
@resource_klasses.each_key do |resource_klass|
|
15
|
+
missed_ids = []
|
16
|
+
|
17
|
+
serializer_config_key = serializer.config_key(resource_klass).gsub("/", "_")
|
18
|
+
context_json = resource_klass.attribute_caching_context(context).to_json
|
19
|
+
context_b64 = JSONAPI.configuration.resource_cache_digest_function.call(context_json)
|
20
|
+
context_key = "ATTR-CTX-#{context_b64.gsub("/", "_")}"
|
21
|
+
|
22
|
+
if resource_klass.caching?
|
23
|
+
cache_ids = []
|
24
|
+
|
25
|
+
@resource_klasses[resource_klass].each_pair do |k, v|
|
26
|
+
# Store the hashcode of the cache_field to avoid storing objects and to ensure precision isn't lost
|
27
|
+
# on timestamp types (i.e. string conversions dropping milliseconds)
|
28
|
+
cache_ids.push([k, resource_klass.hash_cache_field(v[:cache_id])])
|
29
|
+
end
|
30
|
+
|
31
|
+
found_resources = CachedResponseFragment.fetch_cached_fragments(
|
32
|
+
resource_klass,
|
33
|
+
serializer_config_key,
|
34
|
+
cache_ids,
|
35
|
+
context)
|
36
|
+
|
37
|
+
found_resources.each do |found_result|
|
38
|
+
resource = found_result[1]
|
39
|
+
if resource.nil?
|
40
|
+
missed_ids.push(found_result[0])
|
41
|
+
else
|
42
|
+
@resource_klasses[resource_klass][resource.id][:resource] = resource
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
missed_ids = @resource_klasses[resource_klass].keys
|
47
|
+
end
|
48
|
+
|
49
|
+
# fill in any missed resources
|
50
|
+
unless missed_ids.empty?
|
51
|
+
filters = {resource_klass._primary_key => missed_ids}
|
52
|
+
find_opts = {
|
53
|
+
context: context,
|
54
|
+
fields: find_options[:fields] }
|
55
|
+
|
56
|
+
found_resources = resource_klass.find(filters, find_opts)
|
57
|
+
|
58
|
+
found_resources.each do |resource|
|
59
|
+
relationship_data = @resource_klasses[resource_klass][resource.id][:relationships]
|
60
|
+
|
61
|
+
if resource_klass.caching?
|
62
|
+
(id, cr) = CachedResponseFragment.write(
|
63
|
+
resource_klass,
|
64
|
+
resource,
|
65
|
+
serializer,
|
66
|
+
serializer_config_key,
|
67
|
+
context,
|
68
|
+
context_key,
|
69
|
+
relationship_data)
|
70
|
+
|
71
|
+
@resource_klasses[resource_klass][id][:resource] = cr
|
72
|
+
else
|
73
|
+
@resource_klasses[resource_klass][resource.id][:resource] = resource
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
@populated = true
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
def flatten_resource_id_tree(resource_id_tree, flattened_tree = {})
|
84
|
+
resource_id_tree.fragments.each_pair do |resource_rid, fragment|
|
85
|
+
|
86
|
+
resource_klass = resource_rid.resource_klass
|
87
|
+
id = resource_rid.id
|
88
|
+
|
89
|
+
flattened_tree[resource_klass] ||= {}
|
90
|
+
|
91
|
+
flattened_tree[resource_klass][id] ||= { primary: fragment.primary, relationships: {} }
|
92
|
+
flattened_tree[resource_klass][id][:cache_id] ||= fragment.cache
|
93
|
+
|
94
|
+
fragment.related.try(:each_pair) do |relationship_name, related_rids|
|
95
|
+
flattened_tree[resource_klass][id][:relationships][relationship_name] ||= Set.new
|
96
|
+
flattened_tree[resource_klass][id][:relationships][relationship_name].merge(related_rids)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
related_resource_id_trees = resource_id_tree.related_resource_id_trees
|
101
|
+
related_resource_id_trees.try(:each_value) do |related_resource_id_tree|
|
102
|
+
flatten_resource_id_tree(related_resource_id_tree, flattened_tree)
|
103
|
+
end
|
104
|
+
|
105
|
+
flattened_tree
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -1,86 +1,133 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
class ResponseDocument
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
attr_reader :serialized_results
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@serialized_results = []
|
7
|
+
@result_codes = []
|
8
|
+
@error_results = []
|
9
|
+
@global_errors = []
|
10
|
+
|
6
11
|
@options = options
|
7
12
|
|
13
|
+
@top_level_meta = @options.fetch(:base_meta, {})
|
14
|
+
@top_level_links = @options.fetch(:base_links, {})
|
15
|
+
|
8
16
|
@key_formatter = @options.fetch(:key_formatter, JSONAPI.configuration.key_formatter)
|
9
17
|
end
|
10
18
|
|
11
|
-
def
|
12
|
-
|
19
|
+
def has_errors?
|
20
|
+
@error_results.length > 0 || @global_errors.length > 0
|
21
|
+
end
|
13
22
|
|
14
|
-
|
15
|
-
|
23
|
+
def add_result(result, operation)
|
24
|
+
if result.is_a?(JSONAPI::ErrorsOperationResult)
|
25
|
+
# Clear any serialized results
|
26
|
+
@serialized_results = []
|
16
27
|
|
17
|
-
|
18
|
-
|
28
|
+
# In JSONAPI v1 we only have one operation so all errors can be kept together
|
29
|
+
result.errors.each do |error|
|
30
|
+
add_global_error(error)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@serialized_results.push result.to_hash(operation.options[:serializer])
|
34
|
+
@result_codes.push result.code.to_i
|
35
|
+
update_links(operation.options[:serializer], result)
|
36
|
+
update_meta(result)
|
37
|
+
end
|
38
|
+
end
|
19
39
|
|
20
|
-
|
40
|
+
def add_global_error(error)
|
41
|
+
@global_errors.push error
|
21
42
|
end
|
22
43
|
|
23
|
-
def
|
24
|
-
if
|
25
|
-
@
|
44
|
+
def contents
|
45
|
+
if has_errors?
|
46
|
+
return { 'errors' => @global_errors }
|
26
47
|
else
|
27
|
-
@
|
48
|
+
hash = @serialized_results[0]
|
49
|
+
meta = top_level_meta
|
50
|
+
hash.merge!('meta' => meta) unless meta.empty?
|
51
|
+
|
52
|
+
links = top_level_links
|
53
|
+
hash.merge!('links' => links) unless links.empty?
|
54
|
+
|
55
|
+
return hash
|
28
56
|
end
|
29
57
|
end
|
30
58
|
|
31
|
-
|
59
|
+
def status
|
60
|
+
status_codes = if has_errors?
|
61
|
+
@global_errors.collect do |error|
|
62
|
+
error.status.to_i
|
63
|
+
end
|
64
|
+
else
|
65
|
+
@result_codes
|
66
|
+
end
|
67
|
+
|
68
|
+
# Count the unique status codes
|
69
|
+
counts = status_codes.each_with_object(Hash.new(0)) { |code, counts| counts[code] += 1 }
|
70
|
+
|
71
|
+
# if there is only one status code we can return that
|
72
|
+
return counts.keys[0].to_i if counts.length == 1
|
73
|
+
|
74
|
+
# :nocov: not currently used
|
75
|
+
|
76
|
+
# if there are many we should return the highest general code, 200, 400, 500 etc.
|
77
|
+
max_status = 0
|
78
|
+
status_codes.each do |status|
|
79
|
+
code = status.to_i
|
80
|
+
max_status = code if max_status < code
|
81
|
+
end
|
82
|
+
return (max_status / 100).floor * 100
|
83
|
+
# :nocov:
|
84
|
+
end
|
32
85
|
|
33
|
-
|
34
|
-
# and the result of each operation. The keys are then formatted.
|
35
|
-
def top_level_meta
|
36
|
-
meta = @options.fetch(:base_meta, {})
|
86
|
+
private
|
37
87
|
|
38
|
-
|
88
|
+
def update_meta(result)
|
89
|
+
@top_level_meta.merge!(result.meta)
|
39
90
|
|
40
|
-
|
41
|
-
|
91
|
+
if JSONAPI.configuration.top_level_meta_include_record_count && result.respond_to?(:record_count)
|
92
|
+
@top_level_meta[JSONAPI.configuration.top_level_meta_record_count_key] = result.record_count
|
93
|
+
end
|
42
94
|
|
43
|
-
|
44
|
-
|
45
|
-
|
95
|
+
if JSONAPI.configuration.top_level_meta_include_page_count && result.respond_to?(:page_count)
|
96
|
+
@top_level_meta[JSONAPI.configuration.top_level_meta_page_count_key] = result.page_count
|
97
|
+
end
|
46
98
|
|
47
|
-
|
48
|
-
|
99
|
+
if result.warnings.any?
|
100
|
+
@top_level_meta[:warnings] = result.warnings.collect do |warning|
|
101
|
+
warning.to_hash
|
49
102
|
end
|
50
103
|
end
|
104
|
+
end
|
51
105
|
|
52
|
-
|
106
|
+
def top_level_meta
|
107
|
+
@top_level_meta.as_json.deep_transform_keys { |key| @key_formatter.format(key) }
|
53
108
|
end
|
54
109
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
relationship = result.source_resource.class._relationships[result._type.to_sym]
|
70
|
-
unless relationship.exclude_link?(link_name)
|
71
|
-
link = @serializer.link_builder.relationships_related_link(result.source_resource, relationship, query_params(params))
|
72
|
-
end
|
73
|
-
else
|
74
|
-
unless @serializer.link_builder.primary_resource_klass.exclude_link?(link_name)
|
75
|
-
link = @serializer.link_builder.query_link(query_params(params))
|
76
|
-
end
|
77
|
-
end
|
78
|
-
links[link_name] = link unless link.blank?
|
110
|
+
def update_links(serializer, result)
|
111
|
+
@top_level_links.merge!(result.links)
|
112
|
+
|
113
|
+
# Build pagination links
|
114
|
+
if result.is_a?(JSONAPI::ResourceSetOperationResult) ||
|
115
|
+
result.is_a?(JSONAPI::ResourcesSetOperationResult) ||
|
116
|
+
result.is_a?(JSONAPI::RelatedResourcesSetOperationResult)
|
117
|
+
|
118
|
+
result.pagination_params.each_pair do |link_name, params|
|
119
|
+
if result.is_a?(JSONAPI::RelatedResourcesSetOperationResult)
|
120
|
+
relationship = result.source_resource.class._relationships[result._type.to_sym]
|
121
|
+
@top_level_links[link_name] = serializer.link_builder.relationships_related_link(result.source_resource, relationship, query_params(params))
|
122
|
+
else
|
123
|
+
@top_level_links[link_name] = serializer.query_link(query_params(params))
|
79
124
|
end
|
80
125
|
end
|
81
126
|
end
|
127
|
+
end
|
82
128
|
|
83
|
-
|
129
|
+
def top_level_links
|
130
|
+
@top_level_links.deep_transform_keys { |key| @key_formatter.format(key) }
|
84
131
|
end
|
85
132
|
|
86
133
|
def query_params(params)
|
@@ -101,40 +148,5 @@ module JSONAPI
|
|
101
148
|
|
102
149
|
query_params
|
103
150
|
end
|
104
|
-
|
105
|
-
def results_to_hash
|
106
|
-
if @operation_results.has_errors?
|
107
|
-
{ errors: @operation_results.all_errors }
|
108
|
-
else
|
109
|
-
if @operation_results.results.length == 1
|
110
|
-
result = @operation_results.results[0]
|
111
|
-
|
112
|
-
case result
|
113
|
-
when JSONAPI::ResourceOperationResult
|
114
|
-
@serializer.serialize_to_hash(result.resource)
|
115
|
-
when JSONAPI::ResourcesOperationResult
|
116
|
-
@serializer.serialize_to_hash(result.resources)
|
117
|
-
when JSONAPI::RelationshipOperationResult
|
118
|
-
@serializer.serialize_to_relationship_hash(result.parent_resource,
|
119
|
-
result.relationship)
|
120
|
-
when JSONAPI::OperationResult
|
121
|
-
{}
|
122
|
-
end
|
123
|
-
|
124
|
-
elsif @operation_results.results.length > 1
|
125
|
-
resources = []
|
126
|
-
@operation_results.results.each do |result|
|
127
|
-
case result
|
128
|
-
when JSONAPI::ResourceOperationResult
|
129
|
-
resources.push(result.resource)
|
130
|
-
when JSONAPI::ResourcesOperationResult
|
131
|
-
resources.concat(result.resources)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
@serializer.serialize_to_hash(resources)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
151
|
end
|
140
152
|
end
|
data/lib/jsonapi/routing_ext.rb
CHANGED
@@ -18,13 +18,7 @@ module ActionDispatch
|
|
18
18
|
|
19
19
|
def jsonapi_resource(*resources, &_block)
|
20
20
|
@resource_type = resources.first
|
21
|
-
res = JSONAPI::Resource.
|
22
|
-
|
23
|
-
res._routed = true
|
24
|
-
|
25
|
-
unless res.singleton?
|
26
|
-
warn "Singleton routes created for non singleton resource #{res}. Links may not be generated correctly."
|
27
|
-
end
|
21
|
+
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
|
28
22
|
|
29
23
|
options = resources.extract_options!.dup
|
30
24
|
options[:controller] ||= @resource_type
|
@@ -39,8 +33,8 @@ module ActionDispatch
|
|
39
33
|
end
|
40
34
|
|
41
35
|
if res._immutable
|
42
|
-
options[:except] << :create
|
43
|
-
options[:except] << :update
|
36
|
+
options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
|
37
|
+
options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
|
44
38
|
options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy')
|
45
39
|
end
|
46
40
|
|
@@ -70,7 +64,7 @@ module ActionDispatch
|
|
70
64
|
end
|
71
65
|
|
72
66
|
def jsonapi_relationships(options = {})
|
73
|
-
res = JSONAPI::Resource.
|
67
|
+
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
|
74
68
|
res._relationships.each do |relationship_name, relationship|
|
75
69
|
if relationship.is_a?(JSONAPI::Relationship::ToMany)
|
76
70
|
jsonapi_links(relationship_name, options)
|
@@ -84,13 +78,7 @@ module ActionDispatch
|
|
84
78
|
|
85
79
|
def jsonapi_resources(*resources, &_block)
|
86
80
|
@resource_type = resources.first
|
87
|
-
res = JSONAPI::Resource.
|
88
|
-
|
89
|
-
res._routed = true
|
90
|
-
|
91
|
-
if res.singleton?
|
92
|
-
warn "Singleton resource #{res} should use `jsonapi_resource` instead."
|
93
|
-
end
|
81
|
+
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
|
94
82
|
|
95
83
|
options = resources.extract_options!.dup
|
96
84
|
options[:controller] ||= @resource_type
|
@@ -114,8 +102,8 @@ module ActionDispatch
|
|
114
102
|
end
|
115
103
|
|
116
104
|
if res._immutable
|
117
|
-
options[:except] << :create
|
118
|
-
options[:except] << :update
|
105
|
+
options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
|
106
|
+
options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
|
119
107
|
options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy')
|
120
108
|
end
|
121
109
|
|
@@ -159,28 +147,24 @@ module ActionDispatch
|
|
159
147
|
formatted_relationship_name = format_route(link_type)
|
160
148
|
options = links.extract_options!.dup
|
161
149
|
|
162
|
-
res = JSONAPI::Resource.
|
150
|
+
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
|
163
151
|
options[:controller] ||= res._type.to_s
|
164
152
|
|
165
153
|
methods = links_methods(options)
|
166
154
|
|
167
155
|
if methods.include?(:show)
|
168
|
-
match "relationships/#{formatted_relationship_name}",
|
169
|
-
|
170
|
-
action: 'show_relationship', relationship: link_type.to_s, via: [:get],
|
171
|
-
as: "relationships/#{link_type}"
|
156
|
+
match "relationships/#{formatted_relationship_name}", controller: options[:controller],
|
157
|
+
action: 'show_relationship', relationship: link_type.to_s, via: [:get]
|
172
158
|
end
|
173
159
|
|
174
160
|
if res.mutable?
|
175
161
|
if methods.include?(:update)
|
176
|
-
match "relationships/#{formatted_relationship_name}",
|
177
|
-
controller: options[:controller],
|
162
|
+
match "relationships/#{formatted_relationship_name}", controller: options[:controller],
|
178
163
|
action: 'update_relationship', relationship: link_type.to_s, via: [:put, :patch]
|
179
164
|
end
|
180
165
|
|
181
166
|
if methods.include?(:destroy)
|
182
|
-
match "relationships/#{formatted_relationship_name}",
|
183
|
-
controller: options[:controller],
|
167
|
+
match "relationships/#{formatted_relationship_name}", controller: options[:controller],
|
184
168
|
action: 'destroy_relationship', relationship: link_type.to_s, via: [:delete]
|
185
169
|
end
|
186
170
|
end
|
@@ -191,15 +175,14 @@ module ActionDispatch
|
|
191
175
|
formatted_relationship_name = format_route(link_type)
|
192
176
|
options = links.extract_options!.dup
|
193
177
|
|
194
|
-
res = JSONAPI::Resource.
|
178
|
+
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
|
195
179
|
options[:controller] ||= res._type.to_s
|
196
180
|
|
197
181
|
methods = links_methods(options)
|
198
182
|
|
199
183
|
if methods.include?(:show)
|
200
184
|
match "relationships/#{formatted_relationship_name}", controller: options[:controller],
|
201
|
-
action: 'show_relationship', relationship: link_type.to_s, via: [:get]
|
202
|
-
as: "relationships/#{link_type}"
|
185
|
+
action: 'show_relationship', relationship: link_type.to_s, via: [:get]
|
203
186
|
end
|
204
187
|
|
205
188
|
if res.mutable?
|
@@ -221,47 +204,41 @@ module ActionDispatch
|
|
221
204
|
end
|
222
205
|
|
223
206
|
def jsonapi_related_resource(*relationship)
|
224
|
-
source = JSONAPI::Resource.
|
207
|
+
source = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
|
225
208
|
options = relationship.extract_options!.dup
|
226
209
|
|
227
210
|
relationship_name = relationship.first
|
228
211
|
relationship = source._relationships[relationship_name]
|
229
212
|
|
230
|
-
relationship._routed = true
|
231
|
-
|
232
213
|
formatted_relationship_name = format_route(relationship.name)
|
233
214
|
|
234
215
|
if relationship.polymorphic?
|
235
216
|
options[:controller] ||= relationship.class_name.underscore.pluralize
|
236
217
|
else
|
237
|
-
related_resource = JSONAPI::Resource.
|
218
|
+
related_resource = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(relationship.class_name.underscore.pluralize))
|
238
219
|
options[:controller] ||= related_resource._type.to_s
|
239
220
|
end
|
240
221
|
|
241
222
|
match formatted_relationship_name, controller: options[:controller],
|
242
223
|
relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
|
243
|
-
action: '
|
244
|
-
as: "related/#{relationship_name}"
|
224
|
+
action: 'show_related_resource', via: [:get]
|
245
225
|
end
|
246
226
|
|
247
227
|
def jsonapi_related_resources(*relationship)
|
248
|
-
source = JSONAPI::Resource.
|
228
|
+
source = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
|
249
229
|
options = relationship.extract_options!.dup
|
250
230
|
|
251
231
|
relationship_name = relationship.first
|
252
232
|
relationship = source._relationships[relationship_name]
|
253
233
|
|
254
|
-
relationship._routed = true
|
255
|
-
|
256
234
|
formatted_relationship_name = format_route(relationship.name)
|
257
|
-
related_resource = JSONAPI::Resource.
|
235
|
+
related_resource = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(relationship.class_name.underscore))
|
258
236
|
options[:controller] ||= related_resource._type.to_s
|
259
237
|
|
260
238
|
match formatted_relationship_name,
|
261
239
|
controller: options[:controller],
|
262
240
|
relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
|
263
|
-
action: '
|
264
|
-
as: "related/#{relationship_name}"
|
241
|
+
action: 'index_related_resources', via: [:get]
|
265
242
|
end
|
266
243
|
|
267
244
|
protected
|
@@ -274,6 +251,7 @@ module ActionDispatch
|
|
274
251
|
@scope = @scope.parent
|
275
252
|
end
|
276
253
|
# :nocov:
|
254
|
+
|
277
255
|
private
|
278
256
|
|
279
257
|
def resource_type_with_module_prefix(resource = nil)
|