diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 50ac2bbd..cee2f8d0 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -98,6 +98,16 @@ module ActiveModel end end + def self.include_directive_from_options(options) + if options[:include_directive] + options[:include_directive] + elsif options[:include] + JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true) + else + ActiveModelSerializers.default_include_directive + end + end + attr_accessor :object, :root, :scope # `scope_name` is set as :current_user by default in the controller. @@ -185,6 +195,39 @@ module ActiveModel end end + def serializable_hash_for_single_resource(adapter_options, options, adapter_instance) + cached_attributes = adapter_options[:cached_attributes] ||= {} + resource = cached_attributes(options[:fields], cached_attributes, adapter_instance) + relationships = resource_relationships(options) + resource.merge(relationships) + end + + def resource_relationships(options) + relationships = {} + include_directive = options.fetch(:include_directive) + associations(include_directive).each do |association| + relationships[association.key] ||= relationship_value_for(association, options) + end + + relationships + end + + def relationship_value_for(association, options) + return association.options[:virtual_value] if association.options[:virtual_value] + return unless association.serializer && association.serializer.object + + include_directive = options.fetch(:include_directive) + opts = instance_options.merge(include_directive: include_directive[association.key]) + relationship_value = ActiveModelSerializers::Adapter::Attributes.new(association.serializer, opts).serializable_hash(options) + + if association.options[:polymorphic] && relationship_value + polymorphic_type = association.serializer.object.class.name.underscore + relationship_value = { type: polymorphic_type, polymorphic_type.to_sym => relationship_value } + end + + relationship_value + end + protected attr_accessor :instance_options diff --git a/lib/active_model_serializers/adapter/attributes.rb b/lib/active_model_serializers/adapter/attributes.rb index 9a15f616..b32169db 100644 --- a/lib/active_model_serializers/adapter/attributes.rb +++ b/lib/active_model_serializers/adapter/attributes.rb @@ -17,18 +17,8 @@ module ActiveModelSerializers private - def include_directive_from_options(options) - if options[:include_directive] - options[:include_directive] - elsif options[:include] - JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true) - else - ActiveModelSerializers.default_include_directive - end - end - def serializable_hash_for_collection(serializers, options) - include_directive = include_directive_from_options(instance_options) + include_directive = ActiveModel::Serializer.include_directive_from_options(instance_options) instance_options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(serializers, self, include_directive) instance_opts = instance_options.merge(include_directive: include_directive) serializers.map do |serializer| @@ -37,37 +27,8 @@ module ActiveModelSerializers end def serializable_hash_for_single_resource(serializer, instance_options, options) - options[:include_directive] ||= include_directive_from_options(instance_options) - cached_attributes = instance_options[:cached_attributes] ||= {} - resource = serializer.cached_attributes(options[:fields], cached_attributes, self) - relationships = resource_relationships(serializer, options) - resource.merge(relationships) - end - - def resource_relationships(serializer, options) - relationships = {} - include_directive = options.fetch(:include_directive) - serializer.associations(include_directive).each do |association| - relationships[association.key] ||= relationship_value_for(association, options) - end - - relationships - end - - def relationship_value_for(association, options) - return association.options[:virtual_value] if association.options[:virtual_value] - return unless association.serializer && association.serializer.object - - include_directive = options.fetch(:include_directive) - opts = instance_options.merge(include_directive: include_directive[association.key]) - relationship_value = Attributes.new(association.serializer, opts).serializable_hash(options) - - if association.options[:polymorphic] && relationship_value - polymorphic_type = association.serializer.object.class.name.underscore - relationship_value = { type: polymorphic_type, polymorphic_type.to_sym => relationship_value } - end - - relationship_value + options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(instance_options) + serializer.serializable_hash_for_single_resource(instance_options, options, self) end end end