diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 43e537f9..5a9e5c98 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -1,3 +1,4 @@ +require 'active_model/default_serializer' require 'active_model/serializable' require 'active_model/serializer' @@ -22,12 +23,8 @@ module ActiveModel def serializable_array @object.map do |item| - serializer = @options[:each_serializer] || Serializer.serializer_for(item) - if serializer - serializer.new(item).serializable_object(@options.merge(root: nil)) - else - item.as_json - end + serializer = @options[:each_serializer] || Serializer.serializer_for(item) || DefaultSerializer + serializer.new(item).serializable_object(@options.merge(root: nil)) end end alias serializable_object serializable_array diff --git a/lib/active_model/default_serializer.rb b/lib/active_model/default_serializer.rb new file mode 100644 index 00000000..7b5e52ce --- /dev/null +++ b/lib/active_model/default_serializer.rb @@ -0,0 +1,17 @@ +module ActiveModel + # DefaultSerializer + # + # Provides a constant interface for all items + class DefaultSerializer + attr_reader :object + + def initialize(object, options=nil) + @object = object + end + + def serializable_hash(*) + @object.as_json + end + alias serializable_object serializable_hash + end +end diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 91d473fc..4d3ec5fe 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -1,3 +1,4 @@ +require 'active_model/default_serializer' require 'active_model/serializer' module ActiveModel @@ -32,13 +33,8 @@ module ActiveModel end def build_serializer(object) - @serializer_class ||= Serializer.serializer_for(object) - - if @serializer_class - @serializer_class.new(object, @options) - else - object - end + @serializer_class ||= Serializer.serializer_for(object) || DefaultSerializer + @serializer_class.new(object, @options) end class HasOne < Association diff --git a/test/unit/active_model/default_serializer_test.rb b/test/unit/active_model/default_serializer_test.rb new file mode 100644 index 00000000..4acafb78 --- /dev/null +++ b/test/unit/active_model/default_serializer_test.rb @@ -0,0 +1,15 @@ +require 'test_helper' + +module ActiveModel + class DefaultSerializer + class Test < ActiveModel::TestCase + def test_serialize_objects + assert_equal(nil, DefaultSerializer.new(nil).serializable_hash) + assert_equal(1, DefaultSerializer.new(1).serializable_hash) + assert_equal('hi', DefaultSerializer.new('hi').serializable_hash) + obj = Struct.new(:a, :b).new(1, 2) + assert_equal({ a: 1, b: 2 }, DefaultSerializer.new(obj).serializable_hash) + end + end + end +end diff --git a/test/unit/active_model/serializer/has_many_test.rb b/test/unit/active_model/serializer/has_many_test.rb index a4837a5b..c73ce346 100644 --- a/test/unit/active_model/serializer/has_many_test.rb +++ b/test/unit/active_model/serializer/has_many_test.rb @@ -54,6 +54,19 @@ module ActiveModel }, @post_serializer.as_json) end + def test_associations_embedding_nil_objects_serialization_using_as_json + @association.embed = :objects + @post.instance_eval do + def comments + [nil] + end + end + + assert_equal({ + 'title' => 'Title 1', 'body' => 'Body 1', 'comments' => [nil] + }, @post_serializer.as_json) + end + def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options @association.embed = :objects @association.embedded_key = 'root' diff --git a/test/unit/active_model/serializer/has_one_test.rb b/test/unit/active_model/serializer/has_one_test.rb index f7028548..d7cddfd5 100644 --- a/test/unit/active_model/serializer/has_one_test.rb +++ b/test/unit/active_model/serializer/has_one_test.rb @@ -54,6 +54,19 @@ module ActiveModel }, @user_serializer.as_json) end + def test_associations_embedding_nil_objects_serialization_using_as_json + @association.embed = :objects + @user.instance_eval do + def profile + nil + end + end + + assert_equal({ + 'name' => 'Name 1', 'email' => 'mail@server.com', 'profiles' => [nil] + }, @user_serializer.as_json) + end + def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options @association.embed = :objects @association.embedded_key = 'root'