diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb index 2ad9ab002..a659c8d74 100644 --- a/lib/action_controller/serialization.rb +++ b/lib/action_controller/serialization.rb @@ -42,10 +42,9 @@ def use_adapter? @_serializer_opts[:scope] ||= serialization_scope @_serializer_opts[:scope_name] = _serialization_scope - object = serializer.new(resource, @_serializer_opts) - - if serializer == ActiveModel::Serializer.config.array_serializer - resource = ActiveModel::Serializer::Adapter.create(object, @_adapter_opts) unless object.objects.all? {|i| i.nil?} + begin + object = serializer.new(resource, @_serializer_opts) + rescue ActiveModel::Serializer::ArraySerializer::Error else resource = ActiveModel::Serializer::Adapter.create(object, @_adapter_opts) end diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 5a75af42b..8594d14e1 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -211,7 +211,7 @@ def each_association(&block) association_value, options.except(:serializer).merge(serializer_from_options(association_options)) ) - rescue NoMethodError + rescue ActiveModel::Serializer::ArraySerializer::Error # 1. Failure to serialize an element in a collection, e.g. [ {hi: "Steve" } ] will fail # with NoMethodError when the ArraySerializer finds no serializer for the hash { hi: "Steve" }, # and tries to call new on that nil. diff --git a/lib/active_model/serializer/array_serializer.rb b/lib/active_model/serializer/array_serializer.rb index d12b8f483..bd73fd9ea 100644 --- a/lib/active_model/serializer/array_serializer.rb +++ b/lib/active_model/serializer/array_serializer.rb @@ -1,6 +1,7 @@ module ActiveModel class Serializer class ArraySerializer + Error = Class.new(StandardError) include Enumerable delegate :each, to: :@objects @@ -14,7 +15,9 @@ def initialize(objects, options = {}) ActiveModel::Serializer.serializer_for(object) ) - unless serializer_class.nil? + if serializer_class.nil? + fail Error, "No serializer found for object: #{object.inspect}" + else serializer_class.new(object, options.except(:serializer)) end end