mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Replace fail/rescue CollectionSerializer::NoSerializerError with throw/catch :no_serializer (#1767)
This commit is contained in:
parent
c69855bfaa
commit
6c6e45b23f
@ -25,6 +25,8 @@ Fixes:
|
|||||||
- [#1881](https://github.com/rails-api/active_model_serializers/pull/1881) ActiveModelSerializers::Model correctly works with string keys (@yevhene)
|
- [#1881](https://github.com/rails-api/active_model_serializers/pull/1881) ActiveModelSerializers::Model correctly works with string keys (@yevhene)
|
||||||
|
|
||||||
Misc:
|
Misc:
|
||||||
|
- [#1767](https://github.com/rails-api/active_model_serializers/pull/1767) Replace raising/rescuing `CollectionSerializer::NoSerializerError`,
|
||||||
|
throw/catch `:no_serializer`. (@bf4)
|
||||||
- [#1839](https://github.com/rails-api/active_model_serializers/pull/1839) `fields` tests demonstrating usage for both attributes and relationships. (@NullVoxPopuli)
|
- [#1839](https://github.com/rails-api/active_model_serializers/pull/1839) `fields` tests demonstrating usage for both attributes and relationships. (@NullVoxPopuli)
|
||||||
- [#1812](https://github.com/rails-api/active_model_serializers/pull/1812) add a code of conduct (@corainchicago)
|
- [#1812](https://github.com/rails-api/active_model_serializers/pull/1812) add a code of conduct (@corainchicago)
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ It requires an adapter to transform its attributes into a JSON document; it cann
|
|||||||
It may be useful to think of it as a
|
It may be useful to think of it as a
|
||||||
[presenter](http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
|
[presenter](http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
|
||||||
|
|
||||||
The **`ActiveModel::ArraySerializer`** represent a collection of resources as serializers
|
The **`ActiveModel::CollectionSerializer`** represents a collection of resources as serializers
|
||||||
and, if there is no serializer, primitives.
|
and, if there is no serializer, primitives.
|
||||||
|
|
||||||
The **`ActiveModel::Adapter`** describes the structure of the JSON document generated from a
|
The **`ActiveModel::Adapter`** describes the structure of the JSON document generated from a
|
||||||
@ -42,10 +42,9 @@ it is not modified.
|
|||||||
Internally, if no serializer can be found in the controller, the resource is not decorated by
|
Internally, if no serializer can be found in the controller, the resource is not decorated by
|
||||||
ActiveModelSerializers.
|
ActiveModelSerializers.
|
||||||
|
|
||||||
If the collection serializer (ArraySerializer) cannot
|
If the collection serializer (CollectionSerializer) cannot
|
||||||
identify a serializer for a resource in its collection, it raises [`NoSerializerError`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128)
|
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).
|
||||||
which is rescued in `ActiveModel::Serializer::Reflection#build_association` which sets
|
For example, when caught by `Reflection#build_association`, the association value is set directly:
|
||||||
the association value directly:
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
|
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
|
||||||
@ -85,8 +84,8 @@ Details:
|
|||||||
1. The serializer and adapter are created as
|
1. The serializer and adapter are created as
|
||||||
1. `serializer_instance = serializer.new(resource, serializer_opts)`
|
1. `serializer_instance = serializer.new(resource, serializer_opts)`
|
||||||
2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
|
2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
|
||||||
1. **ActiveModel::Serializer::ArraySerializer#new**
|
1. **ActiveModel::Serializer::CollectionSerializer#new**
|
||||||
1. If the `serializer_instance` was a `ArraySerializer` and the `:serializer` serializer_opts
|
1. If the `serializer_instance` was a `CollectionSerializer` and the `:serializer` serializer_opts
|
||||||
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).
|
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).
|
||||||
1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
|
1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
|
||||||
resource as defined by the serializer.
|
resource as defined by the serializer.
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
module ActiveModel
|
module ActiveModel
|
||||||
class Serializer
|
class Serializer
|
||||||
class CollectionSerializer
|
class CollectionSerializer
|
||||||
NoSerializerError = Class.new(StandardError)
|
|
||||||
include Enumerable
|
include Enumerable
|
||||||
delegate :each, to: :@serializers
|
delegate :each, to: :@serializers
|
||||||
|
|
||||||
@ -74,8 +73,9 @@ module ActiveModel
|
|||||||
def serializer_from_resource(resource, serializer_context_class, options)
|
def serializer_from_resource(resource, serializer_context_class, options)
|
||||||
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
|
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
|
||||||
|
|
||||||
if serializer_class.nil? # rubocop:disable Style/GuardClause
|
if serializer_class.nil?
|
||||||
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
|
ActiveModelSerializers.logger.debug "No serializer found for resource: #{resource.inspect}"
|
||||||
|
throw :no_serializer
|
||||||
else
|
else
|
||||||
serializer_class.new(resource, options.except(:serializer))
|
serializer_class.new(resource, options.except(:serializer))
|
||||||
end
|
end
|
||||||
|
|||||||
@ -105,21 +105,24 @@ module ActiveModel
|
|||||||
# @api private
|
# @api private
|
||||||
#
|
#
|
||||||
def build_association(parent_serializer, parent_serializer_options, include_slice = {})
|
def build_association(parent_serializer, parent_serializer_options, include_slice = {})
|
||||||
association_value = value(parent_serializer, include_slice)
|
|
||||||
reflection_options = options.dup
|
reflection_options = options.dup
|
||||||
|
association_value = value(parent_serializer, include_slice)
|
||||||
serializer_class = parent_serializer.class.serializer_for(association_value, reflection_options)
|
serializer_class = parent_serializer.class.serializer_for(association_value, reflection_options)
|
||||||
reflection_options[:include_data] = include_data?(include_slice)
|
reflection_options[:include_data] = include_data?(include_slice)
|
||||||
reflection_options[:links] = @_links
|
reflection_options[:links] = @_links
|
||||||
reflection_options[:meta] = @_meta
|
reflection_options[:meta] = @_meta
|
||||||
|
|
||||||
if serializer_class
|
if serializer_class
|
||||||
begin
|
serializer = catch(:no_serializer) do
|
||||||
reflection_options[:serializer] = serializer_class.new(
|
serializer_class.new(
|
||||||
association_value,
|
association_value,
|
||||||
serializer_options(parent_serializer, parent_serializer_options, reflection_options)
|
serializer_options(parent_serializer, parent_serializer_options, reflection_options)
|
||||||
)
|
)
|
||||||
rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
|
end
|
||||||
|
if serializer.nil?
|
||||||
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
|
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
|
||||||
|
else
|
||||||
|
reflection_options[:serializer] = serializer
|
||||||
end
|
end
|
||||||
elsif !association_value.nil? && !association_value.instance_of?(Object)
|
elsif !association_value.nil? && !association_value.instance_of?(Object)
|
||||||
reflection_options[:virtual_value] = association_value
|
reflection_options[:virtual_value] = association_value
|
||||||
|
|||||||
@ -38,9 +38,10 @@ module ActiveModelSerializers
|
|||||||
|
|
||||||
def find_adapter
|
def find_adapter
|
||||||
return resource unless serializer?
|
return resource unless serializer?
|
||||||
ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
|
adapter = catch :no_serializer do
|
||||||
rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
|
ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
|
||||||
resource
|
end
|
||||||
|
adapter || resource
|
||||||
end
|
end
|
||||||
|
|
||||||
def serializer_instance
|
def serializer_instance
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user