Skip to content

Commit 6c6e45b

Browse files
bf4NullVoxPopuli
authored andcommitted
Replace fail/rescue CollectionSerializer::NoSerializerError with throw/catch :no_serializer (#1767)
1 parent c69855b commit 6c6e45b

File tree

5 files changed

+22
-17
lines changed

5 files changed

+22
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Fixes:
2525
- [#1881](https://github.com/rails-api/active_model_serializers/pull/1881) ActiveModelSerializers::Model correctly works with string keys (@yevhene)
2626

2727
Misc:
28+
- [#1767](https://github.com/rails-api/active_model_serializers/pull/1767) Replace raising/rescuing `CollectionSerializer::NoSerializerError`,
29+
throw/catch `:no_serializer`. (@bf4)
2830
- [#1839](https://github.com/rails-api/active_model_serializers/pull/1839) `fields` tests demonstrating usage for both attributes and relationships. (@NullVoxPopuli)
2931
- [#1812](https://github.com/rails-api/active_model_serializers/pull/1812) add a code of conduct (@corainchicago)
3032

docs/ARCHITECTURE.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ It requires an adapter to transform its attributes into a JSON document; it cann
1515
It may be useful to think of it as a
1616
[presenter](http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
1717

18-
The **`ActiveModel::ArraySerializer`** represent a collection of resources as serializers
18+
The **`ActiveModel::CollectionSerializer`** represents a collection of resources as serializers
1919
and, if there is no serializer, primitives.
2020

2121
The **`ActiveModel::Adapter`** describes the structure of the JSON document generated from a
@@ -42,10 +42,9 @@ it is not modified.
4242
Internally, if no serializer can be found in the controller, the resource is not decorated by
4343
ActiveModelSerializers.
4444

45-
If the collection serializer (ArraySerializer) cannot
46-
identify a serializer for a resource in its collection, it raises [`NoSerializerError`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128)
47-
which is rescued in `ActiveModel::Serializer::Reflection#build_association` which sets
48-
the association value directly:
45+
If the collection serializer (CollectionSerializer) cannot
46+
identify a serializer for a resource in its collection, it throws [`:no_serializer`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128).
47+
For example, when caught by `Reflection#build_association`, the association value is set directly:
4948

5049
```ruby
5150
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
@@ -85,8 +84,8 @@ Details:
8584
1. The serializer and adapter are created as
8685
1. `serializer_instance = serializer.new(resource, serializer_opts)`
8786
2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
88-
1. **ActiveModel::Serializer::ArraySerializer#new**
89-
1. If the `serializer_instance` was a `ArraySerializer` and the `:serializer` serializer_opts
87+
1. **ActiveModel::Serializer::CollectionSerializer#new**
88+
1. If the `serializer_instance` was a `CollectionSerializer` and the `:serializer` serializer_opts
9089
is present, then [that serializer is passed into each resource](https://github.com/rails-api/active_model_serializers/blob/a54d237e2828fe6bab1ea5dfe6360d4ecc8214cd/lib/active_model/serializer/array_serializer.rb#L14-L16).
9190
1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
9291
resource as defined by the serializer.

lib/active_model/serializer/collection_serializer.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module ActiveModel
22
class Serializer
33
class CollectionSerializer
4-
NoSerializerError = Class.new(StandardError)
54
include Enumerable
65
delegate :each, to: :@serializers
76

@@ -74,8 +73,9 @@ def serializers_from_resources
7473
def serializer_from_resource(resource, serializer_context_class, options)
7574
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
7675

77-
if serializer_class.nil? # rubocop:disable Style/GuardClause
78-
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
76+
if serializer_class.nil?
77+
ActiveModelSerializers.logger.debug "No serializer found for resource: #{resource.inspect}"
78+
throw :no_serializer
7979
else
8080
serializer_class.new(resource, options.except(:serializer))
8181
end

lib/active_model/serializer/reflection.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,21 +105,24 @@ def value(serializer, include_slice)
105105
# @api private
106106
#
107107
def build_association(parent_serializer, parent_serializer_options, include_slice = {})
108-
association_value = value(parent_serializer, include_slice)
109108
reflection_options = options.dup
109+
association_value = value(parent_serializer, include_slice)
110110
serializer_class = parent_serializer.class.serializer_for(association_value, reflection_options)
111111
reflection_options[:include_data] = include_data?(include_slice)
112112
reflection_options[:links] = @_links
113113
reflection_options[:meta] = @_meta
114114

115115
if serializer_class
116-
begin
117-
reflection_options[:serializer] = serializer_class.new(
116+
serializer = catch(:no_serializer) do
117+
serializer_class.new(
118118
association_value,
119119
serializer_options(parent_serializer, parent_serializer_options, reflection_options)
120120
)
121-
rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
121+
end
122+
if serializer.nil?
122123
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
124+
else
125+
reflection_options[:serializer] = serializer
123126
end
124127
elsif !association_value.nil? && !association_value.instance_of?(Object)
125128
reflection_options[:virtual_value] = association_value

lib/active_model_serializers/serializable_resource.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ def adapter
3838

3939
def find_adapter
4040
return resource unless serializer?
41-
ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
42-
rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
43-
resource
41+
adapter = catch :no_serializer do
42+
ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
43+
end
44+
adapter || resource
4445
end
4546

4647
def serializer_instance

0 commit comments

Comments
 (0)