Skip to content

Commit

Permalink
Encapsulate serialized_associations; test inline associations
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Dec 1, 2015
1 parent ab6b343 commit 4bdf44a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
21 changes: 13 additions & 8 deletions lib/active_model/serializer/associations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ module Associations
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
Expand Down Expand Up @@ -77,13 +79,16 @@ def has_one(name, options = {}, &block)
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
Expand Down
29 changes: 29 additions & 0 deletions test/serializers/associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,35 @@ def test_associations_custom_keys
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)
Expand Down

0 comments on commit 4bdf44a

Please sign in to comment.