mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-25 07:16:49 +00:00
Make serializer lookup configurable (#1757)
This commit is contained in:
committed by
Yohan Robert
parent
d0de53cbb2
commit
d31d741f43
@@ -60,17 +60,10 @@ module ActiveModel
|
||||
|
||||
# @api private
|
||||
def self.serializer_lookup_chain_for(klass, namespace = nil)
|
||||
chain = []
|
||||
|
||||
resource_class_name = klass.name.demodulize
|
||||
resource_namespace = klass.name.deconstantize
|
||||
serializer_class_name = "#{resource_class_name}Serializer"
|
||||
|
||||
chain.push("#{namespace}::#{serializer_class_name}") if namespace
|
||||
chain.push("#{name}::#{serializer_class_name}") if self != ActiveModel::Serializer
|
||||
chain.push("#{resource_namespace}::#{serializer_class_name}")
|
||||
|
||||
chain
|
||||
lookups = ActiveModelSerializers.config.serializer_lookup_chain
|
||||
Array[*lookups].flat_map do |lookup|
|
||||
lookup.call(klass, self, namespace)
|
||||
end.compact
|
||||
end
|
||||
|
||||
# Used to cache serializer name => serializer class
|
||||
|
||||
@@ -32,6 +32,26 @@ module ActiveModel
|
||||
config.jsonapi_include_toplevel_object = false
|
||||
config.include_data_default = true
|
||||
|
||||
# For configuring how serializers are found.
|
||||
# This should be an array of procs.
|
||||
#
|
||||
# The priority of the output is that the first item
|
||||
# in the evaluated result array will take precedence
|
||||
# over other possible serializer paths.
|
||||
#
|
||||
# i.e.: First match wins.
|
||||
#
|
||||
# @example output
|
||||
# => [
|
||||
# "CustomNamespace::ResourceSerializer",
|
||||
# "ParentSerializer::ResourceSerializer",
|
||||
# "ResourceNamespace::ResourceSerializer" ,
|
||||
# "ResourceSerializer"]
|
||||
#
|
||||
# If CustomNamespace::ResourceSerializer exists, it will be used
|
||||
# for serialization
|
||||
config.serializer_lookup_chain = ActiveModelSerializers::LookupChain::DEFAULT.dup
|
||||
|
||||
config.schema_path = 'test/support/schemas'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,6 +14,7 @@ module ActiveModelSerializers
|
||||
autoload :Adapter
|
||||
autoload :JsonPointer
|
||||
autoload :Deprecate
|
||||
autoload :LookupChain
|
||||
|
||||
class << self; attr_accessor :logger; end
|
||||
self.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
|
||||
|
||||
80
lib/active_model_serializers/lookup_chain.rb
Normal file
80
lib/active_model_serializers/lookup_chain.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
module ActiveModelSerializers
|
||||
module LookupChain
|
||||
# Standard appending of Serializer to the resource name.
|
||||
#
|
||||
# Example:
|
||||
# Author => AuthorSerializer
|
||||
BY_RESOURCE = lambda do |resource_class, _serializer_class, _namespace|
|
||||
serializer_from(resource_class)
|
||||
end
|
||||
|
||||
# Uses the namespace of the resource to find the serializer
|
||||
#
|
||||
# Example:
|
||||
# British::Author => British::AuthorSerializer
|
||||
BY_RESOURCE_NAMESPACE = lambda do |resource_class, _serializer_class, _namespace|
|
||||
resource_namespace = namespace_for(resource_class)
|
||||
serializer_name = serializer_from(resource_class)
|
||||
|
||||
"#{resource_namespace}::#{serializer_name}"
|
||||
end
|
||||
|
||||
# Uses the controller namespace of the resource to find the serializer
|
||||
#
|
||||
# Example:
|
||||
# Api::V3::AuthorsController => Api::V3::AuthorSerializer
|
||||
BY_NAMESPACE = lambda do |resource_class, _serializer_class, namespace|
|
||||
resource_name = resource_class_name(resource_class)
|
||||
namespace ? "#{namespace}::#{resource_name}Serializer" : nil
|
||||
end
|
||||
|
||||
# Allows for serializers to be defined in parent serializers
|
||||
# - useful if a relationship only needs a different set of attributes
|
||||
# than if it were rendered independently.
|
||||
#
|
||||
# Example:
|
||||
# class BlogSerializer < ActiveModel::Serializer
|
||||
# class AuthorSerialier < ActiveModel::Serializer
|
||||
# ...
|
||||
# end
|
||||
#
|
||||
# belongs_to :author
|
||||
# ...
|
||||
# end
|
||||
#
|
||||
# The belongs_to relationship would be rendered with
|
||||
# BlogSerializer::AuthorSerialier
|
||||
BY_PARENT_SERIALIZER = lambda do |resource_class, serializer_class, _namespace|
|
||||
return if serializer_class == ActiveModel::Serializer
|
||||
|
||||
serializer_name = serializer_from(resource_class)
|
||||
"#{serializer_class}::#{serializer_name}"
|
||||
end
|
||||
|
||||
DEFAULT = [
|
||||
BY_PARENT_SERIALIZER,
|
||||
BY_NAMESPACE,
|
||||
BY_RESOURCE_NAMESPACE,
|
||||
BY_RESOURCE
|
||||
].freeze
|
||||
|
||||
module_function
|
||||
|
||||
def namespace_for(klass)
|
||||
klass.name.deconstantize
|
||||
end
|
||||
|
||||
def resource_class_name(klass)
|
||||
klass.name.demodulize
|
||||
end
|
||||
|
||||
def serializer_from_resource_name(name)
|
||||
"#{name}Serializer"
|
||||
end
|
||||
|
||||
def serializer_from(klass)
|
||||
name = resource_class_name(klass)
|
||||
serializer_from_resource_name(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user