diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 0b68fc283..c7c7590fb 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -69,7 +69,7 @@ def self.digest_caller_file(caller_line) serializer.class_attribute :_cache_digest # @api private : Generated end - # Serializers inherit serialized_attributes and _attributes_keys. + # Serializers inherit serialized_attributes, _attributes_keys, and _reflections. # Generates a unique digest for each serializer at load. def self.inherited(base) caller_line = caller.first diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index af627a13c..a07b52ca5 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -13,9 +13,8 @@ module Associations DEFAULT_INCLUDE_TREE = ActiveModel::Serializer::IncludeTree.from_string('*') included do |base| - class << base - attr_accessor :_reflections - end + base.class_attribute :_reflections + base._reflections ||= [] extend ActiveSupport::Autoload autoload :Association @@ -28,8 +27,10 @@ class << base end module ClassMethods + # Serializers inherit _reflections. def inherited(base) - base._reflections = self._reflections.try(:dup) || [] + super + base._reflections = _reflections.dup end # @param [Symbol] name of the association @@ -39,8 +40,8 @@ def inherited(base) # @example # has_many :comments, serializer: CommentSummarySerializer # - def has_many(name, options = {}) - associate HasManyReflection.new(name, options) + def has_many(name, options = {}, &block) + associate(HasManyReflection.new(name, options), block) end # @param [Symbol] name of the association @@ -50,8 +51,8 @@ def has_many(name, options = {}) # @example # belongs_to :author, serializer: AuthorSerializer # - def belongs_to(name, options = {}) - associate BelongsToReflection.new(name, options) + def belongs_to(name, options = {}, &block) + associate(BelongsToReflection.new(name, options), block) end # @param [Symbol] name of the association @@ -61,8 +62,8 @@ def belongs_to(name, options = {}) # @example # has_one :author, serializer: AuthorSerializer # - def has_one(name, options = {}) - associate HasOneReflection.new(name, options) + def has_one(name, options = {}, &block) + associate(HasOneReflection.new(name, options), block) end private @@ -73,11 +74,15 @@ def has_one(name, options = {}) # # @api private # - def associate(reflection) + def associate(reflection, block) self._reflections = _reflections.dup define_method reflection.name do - object.send reflection.name + if block_given? + instance_eval(&block) + else + object.send reflection.name + end end unless method_defined?(reflection.name) self._reflections << reflection