module ActiveModel class Serializer # Holds all the meta-data about an association as it was specified in the # ActiveModel::Serializer class. # # @example # class PostSerializer < ActiveModel::Serializer # has_one :author, serializer: AuthorSerializer # has_many :comments # end # # PostSerializer._reflections #=> # # [ # # HasOneReflection.new(:author, serializer: AuthorSerializer), # # HasManyReflection.new(:comments) # # ] # # So you can inspect reflections in your Adapters. # Reflection = Struct.new(:name, :options) do # Build association. This method is used internally to # build serializer's association by its reflection. # # @param [Serializer] subject is a parent serializer for given association # @param [Hash{Symbol => Object}] parent_serializer_options # # @example # # Given the following serializer defined: # class PostSerializer < ActiveModel::Serializer # has_many :comments, serializer: CommentSummarySerializer # end # # # Then you instantiate your serializer # post_serializer = PostSerializer.new(post, foo: 'bar') # # # to build association for comments you need to get reflection # comments_reflection = PostSerializer._reflections.detect { |r| r.name == :comments } # # and #build_association # comments_reflection.build_association(post_serializer, foo: 'bar') # # @api private # def build_association(subject, parent_serializer_options) association_value = subject.send(name) reflection_options = options.dup serializer_class = ActiveModel::Serializer.serializer_for(association_value, reflection_options) if serializer_class begin serializer = serializer_class.new( association_value, serializer_options(parent_serializer_options, reflection_options) ) rescue ActiveModel::Serializer::ArraySerializer::NoSerializerError reflection_options[:virtual_value] = association_value.try(:as_json) || association_value end elsif !association_value.nil? && !association_value.instance_of?(Object) reflection_options[:virtual_value] = association_value end Association.new(name, serializer, reflection_options) end private def serializer_options(parent_serializer_options, reflection_options) serializer = reflection_options.fetch(:serializer, nil) serializer_options = parent_serializer_options.except(:serializer) serializer_options[:serializer] = serializer if serializer serializer_options end end end end