active_model_serializers/lib/active_model/serializer/associations.rb
Ben Woosley 8ac1f107f4 Remove unnecessary dup in ActiveModel::Serializer::Associations#associate
The `_reflections` are duped on `inherited` - no need to `dup` them
with each addition.
2016-01-12 14:42:07 -08:00

100 lines
3.0 KiB
Ruby

module ActiveModel
class Serializer
# Defines an association in the object should be rendered.
#
# The serializer object should implement the association name
# as a method which should return an array when invoked. If a method
# with the association name does not exist, the association name is
# dispatched to the serialized object.
#
module Associations
extend ActiveSupport::Concern
DEFAULT_INCLUDE_TREE = ActiveModel::Serializer::IncludeTree.from_string('*')
included do
with_options instance_writer: false, instance_reader: true do |serializer|
serializer.class_attribute :_reflections
self._reflections ||= []
end
extend ActiveSupport::Autoload
autoload :Association
autoload :Reflection
autoload :SingularReflection
autoload :CollectionReflection
autoload :BelongsToReflection
autoload :HasOneReflection
autoload :HasManyReflection
end
module ClassMethods
def inherited(base)
super
base._reflections = _reflections.dup
end
# @param [Symbol] name of the association
# @param [Hash<Symbol => any>] options for the reflection
# @return [void]
#
# @example
# has_many :comments, serializer: CommentSummarySerializer
#
def has_many(name, options = {}, &block)
associate(HasManyReflection.new(name, options, block))
end
# @param [Symbol] name of the association
# @param [Hash<Symbol => any>] options for the reflection
# @return [void]
#
# @example
# belongs_to :author, serializer: AuthorSerializer
#
def belongs_to(name, options = {}, &block)
associate(BelongsToReflection.new(name, options, block))
end
# @param [Symbol] name of the association
# @param [Hash<Symbol => any>] options for the reflection
# @return [void]
#
# @example
# has_one :author, serializer: AuthorSerializer
#
def has_one(name, options = {}, &block)
associate(HasOneReflection.new(name, options, block))
end
private
# Add reflection and define {name} accessor.
# @param [ActiveModel::Serializer::Reflection] reflection
# @return [void]
#
# @api private
#
def associate(reflection)
self._reflections << reflection
end
end
# @param [IncludeTree] include_tree (defaults to all associations when not provided)
# @return [Enumerator<Association>]
#
def associations(include_tree = DEFAULT_INCLUDE_TREE)
return unless object
Enumerator.new do |y|
self.class._reflections.each do |reflection|
key = reflection.options.fetch(:key, reflection.name)
next unless include_tree.key?(key)
y.yield reflection.build_association(self, instance_options)
end
end
end
end
end
end