-
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
Allow users to globally opt out of automatic lookup #1295
Conversation
1d157eb
to
5a71255
Compare
5a71255
to
0820d2f
Compare
@trek for the second example, you could specify a serializer under v1? Maybe I miss the point. also, for the first point, I think I would be more in favor of configuring teh suffix, rather than opt out of the lookup. The lookup is very powerful. :-) |
@@ -5,6 +5,7 @@ The following configuration options can be set on `ActiveModel::Serializer.confi | |||
## General | |||
|
|||
- `adapter`: The [adapter](adapters.md) to use. Possible values: `:attributes, :json, :json_api`. Default: `:attributes`. | |||
- `automatic_lookup`: Whether serializer should be automatically looked up or manually provided. Default: `true` |
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.
@trek (hi!)
actually, you can pass adapter: false
in your render (or options[:adapter] = false
if you're outside a controller) and it won't look up a serializer or use an adapter.
ref:
active_model_serializers/lib/active_model/serializable_resource.rb
Lines 54 to 58 in f3403c3
# True when no explicit adapter given, or explicit appear is truthy (non-nil) # False when explicit adapter is falsy (nil or false) def use_adapter? !(adapter_opts.key?(:adapter) && !adapter_opts[:adapter]) end active_model_serializers/lib/action_controller/serialization.rb
Lines 23 to 40 in f3403c3
if !use_adapter? warn 'ActionController::Serialization#use_adapter? has been removed. '\ "Please pass 'adapter: false' or see ActiveSupport::SerializableResource.new" options[:adapter] = false end serializable_resource = ActiveModel::SerializableResource.new(resource, options) if serializable_resource.serializer? serializable_resource.serialization_scope ||= serialization_scope serializable_resource.serialization_scope_name = _serialization_scope begin serializable_resource.adapter rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError resource end else resource end end
That should work for you, and would still be useful to include in this PR, to call that out :)
It should also be mentioned in https://github.com/rails-api/active_model_serializers/blob/master/docs/ARCHITECTURE.md, I think
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.
If that's not sufficient, that's the area of the public API that should be affected.. would love to see a code example of what you're trying to do
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.
👍
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.
So, #1294 was merged, does that address this issue or should we revert it and continue here?
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.
It's unclear if that PR addresses the issue here.
My feeling is that it may be a usage issue (the reason for this PR), but we need more information.
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.
@bf4 (hey!)
#1294 addresses 1 of the 2 problem cases. I think the root problem is that automatic lookup is too aggressive of a strategy for larger apps that want to introduce AMS only for new versions of an existing API. It'd be nice – and frankly safer – to opt out globally and opt-in locally in these cases.
Another riff on this PR is to make that an explicit flag on render calls:
render json: photos, use_serializer: true
But I already personally prefer supplying the specific serializer to the render call. Yes, it's repetitive, but removes the "where the heck is this object turning into this JSON?!?" problem.
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.
Right now AMS automatically includes the ActionController::Serialization mixin. What if you could opt out of that and mix it in to controllers as desired. Would that work? (As opposed to passing in adapter: false
in most of your controllers)
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.
@bf4 are you think that could be an initialization configuration option? something like:
include_action_controller_serialization = true (by default)
?
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.
@trek re:
render json: photos, use_serializer: true
In rails/rails#21496 I have proposed removing use_renderers
since it appears never to have been used or tested. Since your suggestion here has a similar name, I was wondering if it might be related to the use_renderers
method in the Rails Renderer, or just coincidental
v1 in this example (actually several versions in reality) does not use AMS at all nor do we want to through and ensure every every controller specifically opts out. The automatic lookup being always on is very nice for greenfield projects or projects that can go back and update all their calls to |
I wonder if it would be beneficial to override the lookup hierarchy? like, if you have 4 versions of an api, maybe you want to fallback to previous versions, so you don't need to specify all the serializers fro each version? |
unless options[:serializer] || options[:each_serializer] || ActiveModel::Serializer.config.automatic_lookup | ||
return resource | ||
end | ||
|
||
if !use_adapter? |
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.
I suppose you could also make an argument to bring back use_adapter?
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.
(or add ActiveModel::Serializer.config.automatic_lookup
as config.implicit_serializers = false
which would used probably in the serializable resource
What do you think of setting |
I could get behind that, as long as it's documented an well On Tue, Nov 10, 2015, 4:55 AM Benjamin Fleischer notifications@github.com
|
Sorry, I don't quite understand the feedback. Are we just bikeshedding the config name or am I missing something? |
@trek I don't think so. I did bring up different names, but implementation-wise, I think the switch should be somewhere besides I'm thinking there are a few good places to change, not exclusive
Thoughts? |
Closing in favor of #1353 |
Adds an option allowing existing applications to opt out of automatic Serialization lookup.
Two use cases where I've already needed this:
.*Serializer
suffix and you need to migrate over to AMS piecemealTweet
model and want to add aTweetSerializer
for controllers under thev2
namespace but not change existing responses forv1
that are created with a barerender json: a_tweet
If this looks good, I'll get a test in.
Closes #1293