-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Handle serializer namespacing more robustly #886
Comments
I strongly disagree with this proposal. Serializers are meant to present objects as JSONs. This includes but is not limited to rendering responses in controllers. Wider namespaces support is required. Consider elasticsearch-model gem and how does it serialize records. You can customize it by defining It is very important to set lookup namespace with parameter. And when you can do that, then no ActionView's goodies are necessary because specifying |
That's what this does.
Yes. Agreed.
I disagree with this approach entirely and I'm sure the community will agree that it's because of that sort of implementation that AMS was created. People were previously overriding #to_json so this approach would be no different. |
Wow, I wanted to convict myself of premature comment but you were faster. In fact I am still pretty 0.8-minded. When it comes to To give you more concrete example, this is a line of code I would expect to work outside any controller: self.as_json serialization_namespace: ::Indexing Or at least: "Indexing::#{self.class.name}Serializer".safe_constantize.new.as_json Or anything more less similar, I'm not sure if |
Fair point. Can you provide an example where the model would be serialized to json outside the context of a controller? |
@MarkMurphy I can: a worker delivering a json representation of a model object to an external service (e.g. mobile device notification). However, the proposal works fine here, unless I'm missing something. The worker has the responsibility of determining which namespace to use for the serializer. Once that is done, association serializers are chosen with the correct namespaces. |
@MarkMurphy Following comes from the project I was working on: module Concerns
module Indexable
extend ActiveSupport::Concern
# …
# elasticsearch-model expects method of that name
def as_indexed_json options={}
options.reverse_merge! root: false, serialization_namespace: ::Indexing
self.active_model_serializer.new(self, options).as_json
end
end
end I agree this shouldn't be in models, but @eprothro As you wrote, it should preserve namespace when serializing associations. Another important thing is serializing arrays, preferrably without defining yet another array serializer identical with the stock one. |
@eprothro thanks!
Exactly. And perhaps it's possible that the calling instance (i.e. the worker or any class for that matter) could be passed through the same serializer resolver. Who said it has to only work for Controllers? |
@skalee Looks like what you need would just be to manually specify the namespace or serializer. AMS already allows you to do the latter, sort of...(it needs work). In any case, I agree that the developer should be allowed to be explicit in specifying what Example: module Concerns
module Indexable
extend ActiveSupport::Concern
# …
# elasticsearch-model expects method of that name
def as_indexed_json options={}
options.reverse_merge! root: false, namespace: 'elastic_search/index/v1'
ActiveModel::Serializer.new(self, options).as_json
end
end
end In the example above lets assume that a User model includes this concern. The serializer which gets loaded would be: If not found it would then check in the following order:
|
@MarkMurphy I don't think it should be a directory path. Firstly, serializers are regular classes, so specifying parent module seems more natural. Secondly, AMS depends on ActiveModel, not whole Rails, therefore enforcing Rails application layout does not seem appropriate. Example: options.reverse_merge! root: false, namespace: Elasticsearch::Index::V1 |
@MarkMurphy Is |
@skalee no I don't think it does. That was more or less just pseudo code. A syntax I'd like to see because it seems intuitive. |
Curious, it looks like this won't be a part of 0.10 final? Or has there been work on namespacing/versioning that hasn't been mentioned back here? |
@bronson It could make it in :) I haven't seen this issue. Lots of good discussion. cc @beauby and ref https://github.com/skalee/active_model_serializers-namespaces https://github.com/hookercookerman/active_model_version_serializers |
@bronson If you don't mind reverting back to 0.8, then my gem works out of the box. On the other hand, the AMS' interface changed a lot between those versions. If it's an existing project, you may need to implement some controller method to bridge them both. I don't know if it'd be easy or not, it may be project-dependent. @bf4 I need to check if I had some work-in-progress back then. I'm pretty sure I had it all well-thought. |
ref #1442 |
(just fyi) Currently the non-namespaced (or "default" namespace) serializer is prioritized ahead of the namespaced serializer, making it rather unintuitive (the namespaced serializers need to be referenced explicitly all the time). |
Continuing from #144 at the request of @joaomdmoura.
@MarkMurphy and others suggest automatically handling lookup context similar to ActionView. This solves two distinct issues that would provide a good solution to serializer versioning:
More info from Mark's proposal, copied:
If the
get_serializer
method here functioned in the same manner as rails does template lookups for a controller's views, then versioning would be as easy as namespacing your controllers.For example:
Based on the above controllers' namespace, AMS would look for a User serializer at the following locations in order of priority:
app/serializers/api/v1/user_serializer.rb
app/serializers/api/user_serializer.rb
app/serializers/user_serializer.rb
So when api version 2 comes around you'll have the following:
Based on the above controllers' namespace, AMS would look for a User serializer at the following locations in order of priority:
app/serializers/api/v2/user_serializer.rb
app/serializers/api/user_serializer.rb
app/serializers/user_serializer.rb
Routes would look something like this:
Reference:
LookupContext
ViewPaths
The text was updated successfully, but these errors were encountered: