Encapsulate serialized_associations; test inline associations

This commit is contained in:
Benjamin Fleischer 2015-11-30 17:47:12 -06:00
parent 7cbef1b3b5
commit e2903643c5
2 changed files with 42 additions and 8 deletions

View File

@ -13,7 +13,9 @@ module ActiveModel
DEFAULT_INCLUDE_TREE = ActiveModel::Serializer::IncludeTree.from_string('*')
included do |base|
base.class_attribute :_reflections
base.class_attribute :serialized_associations, instance_writer: false # @api public: maps association name to 'Reflection' instance
base.serialized_associations ||= {}
base.class_attribute :_reflections, instance_writer: false
base._reflections ||= []
extend ActiveSupport::Autoload
@ -77,13 +79,16 @@ module ActiveModel
def associate(reflection, block)
self._reflections = _reflections.dup
define_method reflection.name do
if block_given?
instance_eval(&block)
else
object.send reflection.name
end
end unless method_defined?(reflection.name)
reflection_name = reflection.name
if block
serialized_associations[reflection_name] = ->(instance) { instance.instance_eval(&block) }
else
serialized_associations[reflection_name] = ->(instance) { instance.object.send(reflection_name) }
end
define_method reflection_name do
serialized_associations[reflection_name].call(self)
end unless method_defined?(reflection_name)
self._reflections << reflection
end

View File

@ -126,6 +126,35 @@ module ActiveModel
assert expected_association_keys.include? :site
end
class InlineAssociationTestPostSerializer < ActiveModel::Serializer
has_many :comments
has_many :last_comments do
object.comments.last(1)
end
end
def test_virtual_attribute_block
comment1 = ::ARModels::Comment.create!(contents: 'first comment')
comment2 = ::ARModels::Comment.create!(contents: 'last comment')
post = ::ARModels::Post.create!(
title: 'inline association test',
body: 'etc',
comments: [comment1, comment2]
)
actual = serializable(post, adapter: :attributes, serializer: InlineAssociationTestPostSerializer).as_json
expected = {
:comments => [
{ :id => 1, :contents => 'first comment' },
{ :id => 2, :contents => 'last comment' }
],
:last_comments => [
{ :id => 2, :contents => 'last comment' }
]
}
assert_equal expected, actual
end
class NamespacedResourcesTest < Minitest::Test
class ResourceNamespace
Post = Class.new(::Model)