Open
Description
TL;DR
What should be the lookup mechanism when inferring a serializer for a resource?
Proposal
What seems to make most sense is the following:
# resource.class == ::ResNamespace::Resource
# controller.class == ::Api::V1::ResourcesController
lookup_chain = prefixes(controller.class.to_s).map { |p| "#{p}::#{resource.class}Serializer" }
# => [ "::Api::V1::ResourcesController::ResNamespace::ResourceSerializer",
# "::Api::V1::ResNamespace::ResourceSerializer",
# "::Api::ResNamespace::ResourceSerializer",
# "::ResNamespace::ResourceSerializer" ]
# When the resource is serialized as an association of an other serializer, say SerNamespace::OtherResourceSerializer,
# add "SerNamespace::OtherResourceSerializer::ResNamespace::ResourceSerializer" at the beginning of the lookup chain
Implemented in #1436.
Current situation
Work has been done to get us to a more flexible situation in this regard.
The whole automatic lookup can be disabled by setting ActiveModelSerializers.config.automatic_lookup = false
from within an initializer.
Currently, for a resource CoolNamespace::CoolResource
, AMS will look for a CoolResourceSerializer
in the following namespaces:
- If it is being serialized as an association of some other resource using
OtherNamespace::OtherResourceSerializer
, first look forOtherNamespace::OtherResourceSerializer::CoolResourceSerializer
(this is designed so that defining single-purpose serializers for associations is less cumbersome), - otherwise, look for
CoolNamespace::CoolResourceSerializer
(this is kind of the "normal" lookup), - if none is found, recursively do the same for the superclass of
CoolResource
.
Other possible places we might want to look at:
- the calling controller's namespace (Controller namespace lookup. #1436), i.e. when doing
render json: @posts
insideApi::V1::PostsController#index
, look forApi::V1::PostSerializer
, - the calling controller's namespace, concatenated with the resource's namespace, i.e. when doing
render json: @cool_resources
insideApi::V1::CoolResourcesController#index
, look forApi::V1::CoolNamespace::CoolResourceSerializer
(@natematykiewicz), - all of the calling controller's prefix namespaces (in the previous case it would be
::Api::V1
,::Api
, and::
, - the parent serializer's namespace, i.e. when serializing
CoolResource
as an association throughOtherNamespace::OtherResourceSerializer
, look forOtherNamespace::CoolResourceSerializer
(so that when you dorender @post, serializer: Experimental::CoolFeature::PostSerializer
, the post's author can be inferred to beExperimental::CoolFeature::AuthorSerializer
), - a user-specified list of namespaces,
- possibly many other things.
Possible API for user-provided paths
- add callbacks at the beginning and end of the lookup chain
Please chip in with your ideas, use-cases and strong opinions!