-
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
Never mutate controller options #1572
Conversation
@@ -26,13 +26,13 @@ def serialization_scope | |||
respond_to?(_serialization_scope, true) | |||
end | |||
|
|||
def get_serializer(resource, options = {}) | |||
def get_serializer(resource, serializer_options = {}) |
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.
thankyou for specifying which options these are. omg
:-)
👍 |
0bd1eda
to
f436ab9
Compare
Rebased and fixed the tests. |
aad9142
to
094af45
Compare
👍 |
options.fetch(:serialization_context) do | ||
options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, options) | ||
options.freeze | ||
serialization_options = options.deep_dup |
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 I'm not sure if it is good to deep_dup
here as it also dup
the serializer when present and that made the tests fail. That's why I had to do the workaround below. Is this really needed is your opinion?
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.
wouldn't the serializer be a class at this point? How would that be a problem.
I suppose an alternative would be something like strong params where we basically specific which params we want, but that would kill the instance_options
behavior.
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.
Somehow there was some issues with the type
not being duped properly. Therefore the test failed cause the type
method return the wrong value. I didn't dig to much into it though. I can try and spend some more time to figure out why it was duped properly.
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.
Do we actually need to dup and freeze the options at all?
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'm thinking not
On Wed, Mar 30, 2016 at 7:14 AM Yohan Robert [email protected]
wrote:
In lib/action_controller/serialization.rb
#1572 (comment)
:@@ -56,10 +56,15 @@ def use_adapter?
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method| define_method renderer_method do |resource, options|
options.fetch(:serialization_context) do
options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, options)
options.freeze
serialization_options = options.deep_dup
Do we actually need to dup and freeze the options at all?
—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/rails-api/active_model_serializers/pull/1572/files/094af453fe0eb9e8978f6aeec65ec87e22b59a28#r57877815
@groyoh Thanks for helping clean this up. Great work! In the future, would you mind doing me a favor and if there's substantial changes, as there are here, to add a commit, rather than amend the existing one? It make it easier to see what's changed. Thanks! I left a lot of comments here. I've been super swamped lately, and beggars can't be choosers, so I was wondering how you feel about the direction the comments go, code-wise, and if that's something you'd rather talk to me about, wait for me to come back to, or attend to yourself. Thanks, again! 🌈 ✨ |
@@ -62,14 +52,14 @@ def setup | |||
publish_at: @publish_at) | |||
@comment1.post = @post | |||
@comment2.post = @post | |||
@error_resource = ModelWithErrors.new |
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.
Moved here because it was used by many tests.
@bf4 I actually created multiple commit locally but then squashed them up. I admit that it would have been better to leave it as it was for understanding the changes. I'll try to split them up in multiple commits if possible. I also commented on most of the changes 😉 |
094af45
to
5103fe5
Compare
- The controller options are now frozen - The serialization_context is now passed to the adapter via the adapter options and no more via as_json
Sorry about this 😞 |
serializer_options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, serializer_options) | ||
serialization_options = options.deep_dup | ||
if options.key?(:serializer) | ||
serialization_options[:serializer] = options[:serializer] |
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.
you said there was some weird bug caused by duping the serializer
that this fixes?
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.
Yes, I still haven't figured it out but there were three bugs failling. The resulting JSON API types looked like "some_module_some_class"
instead of the values specified via type "post"
. So I assume when the class was duped the _type
wasn't duped properly.
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.
You could probably remove these lines and run the tests to trigger it.
@@ -128,7 +128,7 @@ def success_document(options) | |||
|
|||
if is_collection && serializer.paginated? | |||
hash[:links] ||= {} | |||
hash[:links].update(pagination_links_for(serializer, options)) | |||
hash[:links].update(pagination_links_for(serializer)) | |||
end |
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.
apparently in the rebase i lost that this was @groyoh 's commit
Closed by #1647 |
Purpose
Pagination links incorrectly passing options to
serializable_hash
.Only the renderer should be passing options to
serializable_hash
.It's only working now because we are mutating the controller options which it
later passes to
to_json
which callsserializable_hash
on the adapter.This PR ensures that we do not mutate controller options, which
exposes failures only in the pagination links.
Changes
Caveats
not necessary for this fix.
Related GitHub issues
AMS 0.10.0.rc4 / master
https://github.com/rails-api/active_model_serializers/blob/6b4c8df6fb6bc142ee6a74da51bb26c42a025b3c/lib/active_model_serializers/adapter/json_api.rb
Those options come from the call to
adapter.serializable_hash(options)
which is wrong. They should be passed into the Adapter initializer.