grape-active_model_serializers/lib/grape-active_model_serializers/serializer_resolver.rb
Mateus Nava cce31fe187
fix: Accept nil serializer (#92)
* fix: Accept nil serializer

* Obey the law

---------

Co-authored-by: Mateus Nava <mateus.nava@corp.globo.com>
Co-authored-by: Sami Samhuri <sami@samhuri.net>
2025-06-08 09:21:41 -04:00

107 lines
2.9 KiB
Ruby

module Grape
module ActiveModelSerializers
class SerializerResolver
def initialize(resource, options)
self.resource = resource
self.options = options
end
def serializer
serializer_class&.new(resource, serializer_options)
end
private
attr_accessor :resource, :options
def serializer_class
return @serializer_class if defined?(@serializer_class)
return nil if options.key?(:serializer) && options[:serializer].nil?
@serializer_class = resource_defined_class ||
collection_class ||
options[:serializer] ||
namespace_inferred_class ||
version_inferred_class ||
resource_serializer_class
end
def serializer_options
if collection_serializer? && !options.key?(:serializer)
options.merge(each_serializer_option)
else
options
end
end
def collection_serializer?
serializer_class == ActiveModel::Serializer.config.collection_serializer
end
def each_serializer_option
serializer_class = options[:each_serializer]
serializer_class ||= namespace_inferred_class
serializer_class ||= version_inferred_class
serializer_class ? { serializer: serializer_class } : {}
end
def resource_defined_class
resource.serializer_class if resource.respond_to?(:serializer_class)
end
def collection_class
if resource.respond_to?(:to_ary) || resource.respond_to?(:all)
ActiveModel::Serializer.config.collection_serializer
end
end
def namespace_inferred_class
return nil unless options.key?(:for)
namespace = options[:for].to_s.deconstantize
"#{namespace}::#{resource_serializer_klass}".safe_constantize
end
def version_inferred_class
return nil unless options.key?(:version)
"#{version}::#{resource_serializer_klass}".safe_constantize
end
def version
options[:version].try(:classify)
end
def resource_serializer_klass
@resource_serializer_klass ||= [
resource_namespace,
"#{resource_klass}Serializer"
].compact.join('::')
end
def resource_klass
resource_class.name.demodulize
end
def resource_namespace
klass = resource_class.name.deconstantize
klass.empty? ? nil : klass
end
def resource_class
if resource.respond_to?(:klass)
resource.klass
elsif resource.respond_to?(:to_ary) || resource.respond_to?(:all)
resource.first.class
else
resource.class
end
end
def resource_serializer_class
ActiveModel::Serializer.serializer_for(resource)
end
end
end
end