diff --git a/CHANGELOG.md b/CHANGELOG.md index 84cc350eb..244b3850a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Features: - [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby) Fixes: +- [#1651](https://github.com/rails-api/active_model_serializers/pull/1651) Fix deserialization of nil relationships. (@NullVoxPopuli) - [#1480](https://github.com/rails-api/active_model_serializers/pull/1480) Fix setting of cache_store from Rails configuration. (@bf4) Fix uninentional mutating of value in memory cache store. (@groyoh) - [#1622](https://github.com/rails-api/active_model_serializers/pull/1622) Fragment cache changed from per-record to per-serializer. diff --git a/lib/active_model_serializers/adapter/json_api/deserialization.rb b/lib/active_model_serializers/adapter/json_api/deserialization.rb index ff1d3785a..7b187df2c 100644 --- a/lib/active_model_serializers/adapter/json_api/deserialization.rb +++ b/lib/active_model_serializers/adapter/json_api/deserialization.rb @@ -188,7 +188,9 @@ def parse_relationship(assoc_name, assoc_data, options) end polymorphic = (options[:polymorphic] || []).include?(assoc_name.to_sym) - hash["#{prefix_key}_type".to_sym] = assoc_data[:type] if polymorphic + if polymorphic + hash["#{prefix_key}_type".to_sym] = assoc_data.present? ? assoc_data[:type] : nil + end hash end diff --git a/test/action_controller/json_api/deserialization_test.rb b/test/action_controller/json_api/deserialization_test.rb index 0528dc552..025f857b7 100644 --- a/test/action_controller/json_api/deserialization_test.rb +++ b/test/action_controller/json_api/deserialization_test.rb @@ -9,10 +9,50 @@ def render_parsed_payload parsed_hash = ActiveModelSerializers::Deserialization.jsonapi_parse(params) render json: parsed_hash end + + def render_polymorphic_parsed_payload + parsed_hash = ActiveModelSerializers::Deserialization.jsonapi_parse( + params, + polymorphic: [:restriction_for, :restricted_to] + ) + render json: parsed_hash + end end tests DeserializationTestController + def test_deserialization_of_relationship_only_object + hash = { + 'data' => { + 'type' => 'restraints', + 'relationships' => { + 'restriction_for' => { + 'data' => { + 'type' => 'discounts', + 'id' => '67' + } + }, + 'restricted_to' => { + 'data' => nil + } + } + }, + 'restraint' => {} + } + + post :render_polymorphic_parsed_payload, params: hash + + response = JSON.parse(@response.body) + expected = { + 'restriction_for_id' => '67', + 'restriction_for_type' => 'discounts', + 'restricted_to_id' => nil, + 'restricted_to_type' => nil + } + + assert_equal(expected, response) + end + def test_deserialization hash = { 'data' => {