From 9fa716e45214ab5add156fbc1957ff41a7544230 Mon Sep 17 00:00:00 2001 From: Adman65 Date: Mon, 12 Dec 2011 13:11:36 +0100 Subject: [PATCH] Fixes #12 --- lib/active_model/serializer.rb | 20 ++++++++++++++++++-- test/serializer_test.rb | 30 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 474b2d9d..d52d1bee 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -72,6 +72,10 @@ module ActiveModel def key options[:key] || name end + + def polymorphic? + options[:polymorphic] + end end class HasMany < Config #:nodoc: @@ -93,7 +97,14 @@ module ActiveModel class HasOne < Config #:nodoc: def serialize(object, scope) - object && serializer.new(object, scope).serializable_hash + return unless object + + if polymorphic? + serializer_class = "#{object.class.to_s}Serializer".constantize + serializer_class.new(object, scope).serializable_hash + else + serializer.new(object, scope).serializable_hash + end end def serialize_ids(object, scope) @@ -134,7 +145,7 @@ module ActiveModel class_eval "def #{attr}() object.#{attr} end", __FILE__, __LINE__ end - options[:serializer] ||= begin + options[:serializer] ||= options[:polymorphic] || begin serializer_class = (options[:key] || attr).to_s.classify const_get("#{serializer_class}Serializer") end @@ -281,6 +292,11 @@ module ActiveModel _associations.each do |association| associated_object = send(association.name) hash[association.key] = association.serialize(associated_object, scope) + + if association.polymorphic? && associated_object + polymorphic_type = associated_object.class.to_s.split('::').last + hash["#{association.name}_type".to_sym] = polymorphic_type + end end hash diff --git a/test/serializer_test.rb b/test/serializer_test.rb index b4e50161..acefbb5c 100644 --- a/test/serializer_test.rb +++ b/test/serializer_test.rb @@ -680,4 +680,34 @@ class SerializerTest < ActiveModel::TestCase } }, hash.as_json) end + + class PolymorphicUser < User ; end + + class PolymorphicUserSerializer < ActiveModel::Serializer + attributes :first_name, :last_name + end + + def test_polymorphic_has_one + polymorphic_blog = Class.new do + attr_accessor :writer + end + + polymorphic_serializer = Class.new(ActiveModel::Serializer) do + has_one :writer, :polymorphic => true + end + + user = PolymorphicUser.new + blog = polymorphic_blog.new + blog.writer = user + + serializer = polymorphic_serializer.new(blog, user) + + assert_equal({ + :writer_type => 'PolymorphicUser', + :writer => { + :first_name => "Jose", + :last_name => "Valim" + } + }, serializer.as_json) + end end