-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Namespaced serializers #1338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Namespaced serializers #1338
Conversation
d64adba
to
b44eee1
Compare
@@ -207,6 +207,49 @@ def test_associations_namespaced_resources | |||
end | |||
end | |||
end | |||
|
|||
class NamespaceNestedSerializersTest < Minitest::Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This snippet from the PR description would also make a great test showing the old behavior and the behavior this PR introduces. It wasn't obvious to me from the examples why you'd want to 'step back' one level in the serializer lookup.
It simply modifies Serializer#serializer_lookup_chain_for to add all
of the possible levels of namespaces based on the current serializer.
With this patch for example if we have:class Public::V1::PostSerializer
belongs_to :author
endclass Public::V1::AuthorSerializer
end
we will wind up with the following items in the lookup chain for an
author when serializing a Post with Public::V1::PostSerializer:['Public::V1::PostSerializer::AuthorSerializer',
'Public::V1::AuthorSerializer', 'Public::AuthorSerializer',
'::AuthorSerializer']
chain.push("#{name}::#{serializer_class_name}") if self != ActiveModel::Serializer | ||
if self != ActiveModel::Serializer | ||
chain.push("#{name}::#{serializer_class_name}") | ||
chain.push(*name.deconstantize.split('::').each_with_object([]) { |element, array| array.push((array.last ? array.last + '::' : '') + element) }.reverse.map { |k| k + "::#{serializer_class_name}" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A slightly shorter version that leads to the same result:
klass.to_s.split('::').reverse.reduce([]) { |a, e| a + [[e] + Array(a.last)] }.reverse
The reason why I'm not sure it's that useful is because the "magic" can get confusing in some cases (think of having nested serializers like |
Totally get that the magic can get confusing but there is not currently a valid solution supporting all uses with namespaced versions. Specifically polymorphic associations. I wouldn't be opposed to something more explicit but it would need to work with controller and non rendering paths. |
Two possible solutions (for which I issued PRs at some point but they ended up in limbo):
|
Would 1 work outside of a controller render? I can't find much docs on the whole The root serializer doesn't allow for any nesting. For example we have Public::V1 with most of our stuff but then a Public::V1::ConversationElement namespace with some polymorphic resources that reference things in the parent namespace that aren't polymorphic Maybe the root serializer specifies just the highest level in which to look. I was thinking it could be an actual class level setting that you could set on a parent serializer to opt-in to this feature. Something like: class Public::V1::Serializer < ActiveModel::Serializer
root_namespace 'Public::V1'
end
class Public::V1::CustomerSerializer < Public::V1::Serializer
end |
|
Are we still working on this? |
ref: #1436 |
Adds support for finding serializers based on the "current" serializers namespace to support things like serializer versioning. Without this you have to be explicit in naming which serializer to use in all of your serializer associations. That's OK usually (albeit annoying) but it breaks polymorphism since you can't really specify the right serializer ahead of time. I came across a bunch of PRs such as rails-api#1225 that talk about different versions of namespacing based on modules or controllers or whatever and some of them even talk about supporting serializer namespaces but I have been unable to find one that actually does this part of it. If there is already work being done for this, feel free to ignore this PR but we needed this for our current work. This PR builds on top of the work done by @beauby in rails-api#1225 to add support for namespaced serializer lookups. @beauby's work only allowed for actual nesting of serializers withing a namespaced serializer (e.g. for overrides) but did not actually walk up the tree to siblings or serializers farther up the inheritance/namespace tree. It simply modifies `Serializer#serializer_lookup_chain_for` to add all of the possible levels of namespaces based on the current serializer. With this patch for example if we have: ```ruby class Public::V1::PostSerializer belongs_to :author end class Public::V1::AuthorSerializer end ``` we will wind up with the following items in the lookup chain for an author when serializing a Post with Public::V1::PostSerializer: ```ruby ['Public::V1::PostSerializer::AuthorSerializer', 'Public::V1::AuthorSerializer', 'Public::AuthorSerializer', '::AuthorSerializer'] ```
I'm certainly still hopeful to get this in. Would rather not have to keep rebasing my fork/branch. :) Also open to other working solutions to the original problem if there has been something added that I have missed. |
b44eee1
to
2553d68
Compare
Rebased. |
Adds support for finding serializers based on the "current" serializers
namespace to support things like serializer versioning. Without this you
have to be explicit in naming which serializer to use in all of your
serializer associations. That's OK usually (albeit annoying) but it
breaks polymorphism since you can't really specify the right serializer
ahead of time.
I came across a bunch of PRs such as #1225 that talk about different
versions of namespacing based on modules or controllers or whatever and
some of them even talk about supporting serializer namespaces but I have
been unable to find one that actually does this part of it. If there is
already work being done for this, feel free to ignore this PR but we
needed this for our current work.
This PR builds on top of the work done by @beauby in #1225 to add
support for namespaced serializer lookups. @beauby's work only allowed
for actual nesting of serializers withing a namespaced serializer (e.g.
for overrides) but did not actually walk up the tree to siblings or
serializers farther up the inheritance/namespace tree.
It simply modifies
Serializer#serializer_lookup_chain_for
to add allof the possible levels of namespaces based on the current serializer.
With this patch for example if we have:
we will wind up with the following items in the lookup chain for an
author when serializing a Post with Public::V1::PostSerializer: