Skip to content

Commit 005306c

Browse files
saravanaklgebhardt
authored andcommitted
Support creating/updating polymorphic has-many relationships
1 parent 3df43c7 commit 005306c

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

lib/jsonapi/request_parser.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -521,19 +521,15 @@ def parse_to_many_relationship(link_value, relationship, &add_result)
521521

522522
links_object = parse_to_many_links_object(linkage)
523523

524-
# Since we do not yet support polymorphic to_many relationships we will raise an error if the type does not match the
525-
# relationship's type.
526-
# ToDo: Support Polymorphic relationships
527-
528524
if links_object.length == 0
529525
add_result.call([])
530526
else
531-
if links_object.length > 1 || !links_object.has_key?(unformat_key(relationship.type).to_s)
532-
fail JSONAPI::Exceptions::TypeMismatch.new(links_object[:type])
533-
end
534-
527+
defined_relationship_resource = Resource.resource_for(@resource_klass.module_path + unformat_key(relationship.type).to_s)
535528
links_object.each_pair do |type, keys|
536529
relationship_resource = Resource.resource_for(@resource_klass.module_path + unformat_key(type).to_s)
530+
if !relationship_resource.ancestors.include?(defined_relationship_resource)
531+
fail JSONAPI::Exceptions::TypeMismatch.new(links_object[:type])
532+
end
537533
add_result.call relationship_resource.verify_keys(keys, @context)
538534
end
539535
end

test/integration/requests/request_test.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,52 @@ def test_post_single
211211
assert_jsonapi_response 201
212212
end
213213

214+
def test_post_polymorphic
215+
post '/people', params:
216+
{
217+
'data' => {
218+
'type' => 'people',
219+
'attributes' => {
220+
'name' => 'Reo',
221+
'email' => 'reo@xyz.fake',
222+
'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00',
223+
},
224+
'relationships' => {
225+
'vehicles' => {'data' => [{'type' => 'car', 'id' => '1'}]},
226+
}
227+
}
228+
}.to_json,
229+
headers: {
230+
'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE,
231+
'Accept' => JSONAPI::MEDIA_TYPE
232+
}
233+
234+
assert_jsonapi_response 201
235+
end
236+
237+
def test_post_polymorphic_invalid
238+
post '/people', params:
239+
{
240+
'data' => {
241+
'type' => 'people',
242+
'attributes' => {
243+
'name' => 'Reo',
244+
'email' => 'reo@xyz.fake',
245+
'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00',
246+
},
247+
'relationships' => {
248+
'vehicles' => {'data' => [{'type' => 'author', 'id' => '1'}]},
249+
}
250+
}
251+
}.to_json,
252+
headers: {
253+
'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE,
254+
'Accept' => JSONAPI::MEDIA_TYPE
255+
}
256+
257+
assert_jsonapi_response 400, msg: "Submitting a thing as a vehicle should raise a type mismatch error"
258+
end
259+
214260
def test_post_single_missing_data_contents
215261
post '/posts', params:
216262
{

0 commit comments

Comments
 (0)