From d70dafd8adafd2883188b5ac905074e0ec83fbd1 Mon Sep 17 00:00:00 2001 From: Nika Jukic Date: Wed, 26 May 2021 09:55:57 +0200 Subject: [PATCH 1/2] Always add _attributes params for empty or nil relationships --- .../empty_to_many_relation_handler.rb | 22 +++++++++++++++++++ .../empty_to_one_relation_handler.rb | 22 +++++++++++++++++++ .../default_handlers/nil_relation_handler.rb | 2 +- lib/jsonapi_parameters/handlers.rb | 3 +++ lib/jsonapi_parameters/translator.rb | 17 ++++++++++++-- spec/support/inputs_outputs_pairs.rb | 10 +++++---- 6 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 lib/jsonapi_parameters/default_handlers/empty_to_many_relation_handler.rb create mode 100644 lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb diff --git a/lib/jsonapi_parameters/default_handlers/empty_to_many_relation_handler.rb b/lib/jsonapi_parameters/default_handlers/empty_to_many_relation_handler.rb new file mode 100644 index 0000000..a0d3dad --- /dev/null +++ b/lib/jsonapi_parameters/default_handlers/empty_to_many_relation_handler.rb @@ -0,0 +1,22 @@ +require 'active_support/inflector' + +module JsonApi + module Parameters + module Handlers + module DefaultHandlers + class EmptyToManyRelationHandler < BaseHandler + include ActiveSupport::Inflector + + attr_reader :with_inclusion, :vals, :key + + def handle + [ + ["#{pluralize(relationship_key)}_attributes".to_sym, []], + ["#{singularize(relationship_key)}_ids".to_sym, []] + ] + end + end + end + end + end +end diff --git a/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb b/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb new file mode 100644 index 0000000..9ffe18f --- /dev/null +++ b/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb @@ -0,0 +1,22 @@ +require 'active_support/inflector' + +module JsonApi + module Parameters + module Handlers + module DefaultHandlers + class EmptyToOneRelationHandler < BaseHandler + include ActiveSupport::Inflector + + attr_reader :with_inclusion, :vals, :key + + def handle + [ + ["#{singularize(relationship_key)}_attributes".to_sym, []], + ["#{singularize(relationship_key)}_id".to_sym, nil] + ] + end + end + end + end + end +end diff --git a/lib/jsonapi_parameters/default_handlers/nil_relation_handler.rb b/lib/jsonapi_parameters/default_handlers/nil_relation_handler.rb index ddc43e9..3592dec 100644 --- a/lib/jsonapi_parameters/default_handlers/nil_relation_handler.rb +++ b/lib/jsonapi_parameters/default_handlers/nil_relation_handler.rb @@ -20,7 +20,7 @@ def handle end # Handle with empty hash. - ToOneRelationHandler.new(relationship_key, {}, {}).handle + EmptyToOneRelationHandler.new(relationship_key, {}, {}).handle end end end diff --git a/lib/jsonapi_parameters/handlers.rb b/lib/jsonapi_parameters/handlers.rb index f74dd06..f650a6b 100644 --- a/lib/jsonapi_parameters/handlers.rb +++ b/lib/jsonapi_parameters/handlers.rb @@ -1,6 +1,8 @@ require_relative 'default_handlers/nil_relation_handler' require_relative 'default_handlers/to_many_relation_handler' require_relative 'default_handlers/to_one_relation_handler' +require_relative 'default_handlers/empty_to_one_relation_handler' +require_relative 'default_handlers/empty_to_many_relation_handler' module JsonApi module Parameters @@ -8,6 +10,7 @@ module Handlers include DefaultHandlers DEFAULT_HANDLER_SET = { + empty_to_many: EmptyToManyRelationHandler, to_many: ToManyRelationHandler, to_one: ToOneRelationHandler, nil: NilRelationHandler diff --git a/lib/jsonapi_parameters/translator.rb b/lib/jsonapi_parameters/translator.rb index b7574b6..11aabb7 100644 --- a/lib/jsonapi_parameters/translator.rb +++ b/lib/jsonapi_parameters/translator.rb @@ -72,6 +72,8 @@ def handle_relationships(param, relationship_key, relationship_value) Handlers.handlers[Handlers.resource_handlers[relationship_key]] else case relationship_value + when [] + Handlers.handlers[:empty_to_many] when Array Handlers.handlers[:to_many] when Hash @@ -83,15 +85,26 @@ def handle_relationships(param, relationship_key, relationship_value) end end - key, val = handler.call(*handler_args) + handled_params = handler.call(*handler_args) - param[key] = handle_nested_relationships(val) + add_relationships_to_params(handled_params, param) param ensure decrement_stack_level end + def add_relationships_to_params(handled_params, param) + if handled_params.all?(Array) + handled_params.each do |key, val| + param[key] = handle_nested_relationships(val) + end + else + key, val = *handled_params + param[key] = handle_nested_relationships(val) + end + end + def handle_nested_relationships(val) # We can only consider Hash relationships (which imply to-one relationship) and Array relationships (which imply to-many). # Each type has a different handling method, though in both cases we end up passing the nested relationship recursively to handle_relationship diff --git a/spec/support/inputs_outputs_pairs.rb b/spec/support/inputs_outputs_pairs.rb index b9053d0..9d43c4d 100644 --- a/spec/support/inputs_outputs_pairs.rb +++ b/spec/support/inputs_outputs_pairs.rb @@ -482,7 +482,8 @@ module JsonApi::Parameters::Testing photo: { title: 'Ember Hamster', src: 'http://example.com/images/productivity.png', - photographer_ids: [] + photographer_ids: [], + photographers_attributes: [] } } ] }, @@ -505,7 +506,8 @@ module JsonApi::Parameters::Testing account: { name: 'Bob Loblaw', profile_url: 'http://example.com/images/no-nonsense.png', - owner_id: nil + owner_id: nil, + owner_attributes: [] } } ] }, @@ -526,7 +528,7 @@ module JsonApi::Parameters::Testing }, { user: { - name: 'Adam Joe', practice_area_ids: [], + name: 'Adam Joe', practice_area_ids: [], practice_areas_attributes: [] } } ] }, @@ -546,7 +548,7 @@ module JsonApi::Parameters::Testing }, { user: { - name: 'Adam Joe', practice_area_ids: [], + name: 'Adam Joe', practice_area_ids: [], practice_areas_attributes: [] } } ] }, From 9e63c83ce492550cacb5020edf98adbbbd260679 Mon Sep 17 00:00:00 2001 From: Nika Jukic Date: Wed, 26 May 2021 10:50:21 +0200 Subject: [PATCH 2/2] Use {} instead of [] for empty has one _attributes --- .../default_handlers/empty_to_one_relation_handler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb b/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb index 9ffe18f..a4b7fa7 100644 --- a/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb +++ b/lib/jsonapi_parameters/default_handlers/empty_to_one_relation_handler.rb @@ -11,7 +11,7 @@ class EmptyToOneRelationHandler < BaseHandler def handle [ - ["#{singularize(relationship_key)}_attributes".to_sym, []], + ["#{singularize(relationship_key)}_attributes".to_sym, {}], ["#{singularize(relationship_key)}_id".to_sym, nil] ] end