From 73eae19b3d0b8a3c03fda566a208eeee6720beed Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Sun, 30 Apr 2017 22:52:41 -0500 Subject: [PATCH] Return null resource object identifier for blank id Also, fix test where attributes were included when id was "" ``` 1) Failure: ActionController::Serialization::AdapterSelectorTest#test_render_using_adapter_override [test/action_c$ntroller/adapter_selector_test.rb:53]: --- expected +++ actual @@ -1 +1 @@ -"{\"data\":{\"id\":\"\",\"type\":\"profiles\",\"attributes\":{\"name\":\"Name 1\",\"description\":\"Description 1\"}}}" +"{\"data\":null}" ``` --- .../adapter/json_api.rb | 44 ++++++++++++------- .../adapter/json_api/resource_identifier.rb | 2 + .../adapter_selector_test.rb | 4 +- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/lib/active_model_serializers/adapter/json_api.rb b/lib/active_model_serializers/adapter/json_api.rb index c252deaf..b225416b 100644 --- a/lib/active_model_serializers/adapter/json_api.rb +++ b/lib/active_model_serializers/adapter/json_api.rb @@ -295,20 +295,8 @@ module ActiveModelSerializers # {http://jsonapi.org/format/#document-resource-objects Document Resource Objects} def resource_object_for(serializer, include_slice = {}) - resource_object = serializer.fetch(self) do - resource_object = ResourceIdentifier.new(serializer, instance_options).as_json + resource_object = data_for(serializer, include_slice) - requested_fields = fieldset && fieldset.fields_for(resource_object[:type]) - attributes = attributes_for(serializer, requested_fields) - resource_object[:attributes] = attributes if attributes.any? - resource_object - end - - requested_associations = fieldset.fields_for(resource_object[:type]) || '*' - relationships = relationships_for(serializer, requested_associations, include_slice) - resource_object[:relationships] = relationships if relationships.any? - - links = links_for(serializer) # toplevel_links # definition: # allOf @@ -322,7 +310,10 @@ module ActiveModelSerializers # prs: # https://github.com/rails-api/active_model_serializers/pull/1247 # https://github.com/rails-api/active_model_serializers/pull/1018 - resource_object[:links] = links if links.any? + if (links = links_for(serializer)).any? + resource_object ||= {} + resource_object[:links] = links + end # toplevel_meta # alias meta @@ -332,12 +323,33 @@ module ActiveModelSerializers # { # :'git-ref' => 'abc123' # } - meta = meta_for(serializer) - resource_object[:meta] = meta unless meta.blank? + if (meta = meta_for(serializer)).present? + resource_object ||= {} + resource_object[:meta] = meta + end resource_object end + def data_for(serializer, include_slice) + data = serializer.fetch(self) do + resource_object = ResourceIdentifier.new(serializer, instance_options).as_json + break nil if resource_object.nil? + + requested_fields = fieldset && fieldset.fields_for(resource_object[:type]) + attributes = attributes_for(serializer, requested_fields) + resource_object[:attributes] = attributes if attributes.any? + resource_object + end + data.tap do |resource_object| + next if resource_object.nil? + # NOTE(BF): the attributes are cached above, separately from the relationships, below. + requested_associations = fieldset.fields_for(resource_object[:type]) || '*' + relationships = relationships_for(serializer, requested_associations, include_slice) + resource_object[:relationships] = relationships if relationships.any? + end + end + # {http://jsonapi.org/format/#document-resource-object-relationships Document Resource Object Relationship} # relationships # definition: diff --git a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb index 8931f899..3a235f2b 100644 --- a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +++ b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb @@ -23,6 +23,7 @@ module ActiveModelSerializers end def self.for_type_with_id(type, id, options) + return nil if id.blank? { id: id.to_s, type: type_for(:no_class_needed, type, options) @@ -36,6 +37,7 @@ module ActiveModelSerializers end def as_json + return nil if id.blank? { id: id, type: type } end diff --git a/test/action_controller/adapter_selector_test.rb b/test/action_controller/adapter_selector_test.rb index db93573b..3373de7c 100644 --- a/test/action_controller/adapter_selector_test.rb +++ b/test/action_controller/adapter_selector_test.rb @@ -19,7 +19,7 @@ module ActionController end def render_using_adapter_override - @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1') + @profile = Profile.new(id: 'render_using_adapter_override', name: 'Name 1', description: 'Description 1', comments: 'Comments 1') render json: @profile, adapter: :json_api end @@ -41,7 +41,7 @@ module ActionController expected = { data: { - id: @controller.instance_variable_get(:@profile).id.to_s, + id: 'render_using_adapter_override', type: 'profiles', attributes: { name: 'Name 1',