diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 5e3477905..45e929ed5 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -366,9 +366,10 @@ def associations(include_directive = ActiveModelSerializers.default_include_dire def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) adapter_options ||= {} options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options) - if (fieldset = adapter_options[:fieldset]) - options[:fields] = fieldset.fields_for(json_key) - end + + fieldset = adapter_options[:fieldset] + options[:fields] = fieldset.fields_for(json_key) if fieldset + resource = attributes_hash(adapter_options, options, adapter_instance) relationships = associations_hash(adapter_options, options, adapter_instance) resource.merge(relationships) diff --git a/lib/active_model_serializers/adapter/attributes.rb b/lib/active_model_serializers/adapter/attributes.rb index 3372e2be8..ff9fedd64 100644 --- a/lib/active_model_serializers/adapter/attributes.rb +++ b/lib/active_model_serializers/adapter/attributes.rb @@ -5,7 +5,10 @@ module Adapter class Attributes < Base def initialize(*) super - instance_options[:fieldset] ||= ActiveModel::Serializer::Fieldset.new(fields_to_fieldset(instance_options.delete(:fields))) + + fields = instance_options.delete(:fields) + fieldset = fields_to_fieldset(fields) + instance_options[:fieldset] = ActiveModel::Serializer::Fieldset.new(fieldset) if fieldset end def serializable_hash(options = nil) @@ -19,9 +22,11 @@ def serializable_hash(options = nil) private def fields_to_fieldset(fields) - return fields if fields.nil? + return if fields.nil? + resource_fields = [] relationship_fields = {} + fields.each do |field| case field when Symbol, String then resource_fields << field @@ -29,6 +34,7 @@ def fields_to_fieldset(fields) else fail ArgumentError, "Unknown conversion of fields to fieldset: '#{field.inspect}' in '#{fields.inspect}'" end end + relationship_fields.merge!(serializer.json_key.to_sym => resource_fields) end end diff --git a/lib/active_model_serializers/adapter/json_api.rb b/lib/active_model_serializers/adapter/json_api.rb index 83c75ea82..187319ed5 100644 --- a/lib/active_model_serializers/adapter/json_api.rb +++ b/lib/active_model_serializers/adapter/json_api.rb @@ -53,7 +53,8 @@ def self.fragment_cache(cached_hash, non_cached_hash, root = true) def initialize(serializer, options = {}) super @include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true) - @fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields)) + option_fields = options.delete(:fields) + @fieldset = ActiveModel::Serializer::Fieldset.new(option_fields) if option_fields end # {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure} @@ -348,7 +349,8 @@ def data_for(serializer, include_slice) 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]) || '*' + requested_fields = fieldset && fieldset.fields_for(resource_object[:type]) + requested_associations = requested_fields || '*' relationships = relationships_for(serializer, requested_associations, include_slice) resource_object[:relationships] = relationships if relationships.any? end