Skip to content

Commit

Permalink
Handle special-case of Array serializer with unserializable elements
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Jun 22, 2015
1 parent d26838f commit 3d98c3c
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 6 deletions.
7 changes: 3 additions & 4 deletions lib/action_controller/serialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)

This comment has been minimized.

Copy link
@bf4

bf4 Jun 22, 2015

Author Member

what do you think about renaming object to serializer_instance?

This comment has been minimized.

Copy link
@bf4

bf4 Jun 22, 2015

Author Member

With this change, we no longer need ArraySerializer#objects, but I think it's still useful to have. YAGNI?

rescue ActiveModel::Serializer::ArraySerializer::Error
else
resource = ActiveModel::Serializer::Adapter.create(object, @_adapter_opts)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion lib/active_model/serializer/array_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module ActiveModel
class Serializer
class ArraySerializer
Error = Class.new(StandardError)
include Enumerable
delegate :each, to: :@objects

Expand All @@ -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}"

This comment has been minimized.

Copy link
@bf4

bf4 Jun 22, 2015

Author Member

Because we're calling the map in initialize, there's really no graceful way to handle this, except 1) an exception 2) a either a block the yields the object or some flag that we need to check before using the instance.

I tried writing a PassThroughSerializer but the interface of the serializer required by the adapter was too broad.

else
serializer_class.new(object, options.except(:serializer))
end
end
Expand Down

0 comments on commit 3d98c3c

Please sign in to comment.