-
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,13 +26,13 @@ def serialization_scope | |
respond_to?(_serialization_scope, true) | ||
end | ||
|
||
def get_serializer(resource, serializer_options = {}) | ||
def get_serializer(resource, serialization_options = {}) | ||
if !use_adapter? | ||
warn 'ActionController::Serialization#use_adapter? has been removed. '\ | ||
"Please pass 'adapter: false' or see ActiveSupport::SerializableResource.new" | ||
serializer_options[:adapter] = false | ||
serialization_options[:adapter] = false | ||
end | ||
serializable_resource = ActiveModel::SerializableResource.new(resource, serializer_options) | ||
serializable_resource = ActiveModel::SerializableResource.new(resource, serialization_options) | ||
if serializable_resource.serializer? | ||
serializable_resource.serialization_scope ||= serialization_scope | ||
serializable_resource.serialization_scope_name = _serialization_scope | ||
|
@@ -57,11 +57,14 @@ def use_adapter? | |
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method| | ||
define_method renderer_method do |resource, options| | ||
options.freeze | ||
serializer_options = options.deep_dup | ||
serializer_options.fetch(:serialization_context) do | ||
serializer_options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, serializer_options) | ||
serialization_options = options.deep_dup | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bf4 I'm not sure if it is good to There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somehow there was some issues with the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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]
|
||
if options.key?(:serializer) | ||
serialization_options[:serializer] = options[:serializer] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you said there was some weird bug caused by duping the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
end | ||
serializable_resource = get_serializer(resource, serializer_options) | ||
unless serialization_options.key?(:serialization_context) | ||
serialization_options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, serialization_options) | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using fetch would be the more idiomatic way to do this, and is also easier to read. @groyoh is there a reason you changed this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't fetch main use case supposed to be "retrieving an object"? I changed it because for me using fetch when we don't use the return value feels weird. But I can revert this change if needed. |
||
serializable_resource = get_serializer(resource, serialization_options) | ||
super(serializable_resource, options) | ||
end | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
require 'active_model_serializers/adapter' | ||
module ActiveModel | ||
class SerializableResource | ||
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter, :meta, :meta_key, :links]) | ||
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter, :meta, :meta_key, :links, :serialization_context]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose the problem here will be if a serializer can use url helper to make links without the serialization context.. but that's not anything anyone is working on now |
||
include ActiveModelSerializers::Logging | ||
|
||
delegate :serializable_hash, :as_json, :to_json, to: :adapter | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# coding: utf-8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was there a problem not having this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like emacs automatically added it. Will fix it. |
||
# {http://jsonapi.org/format/ JSON API specification} | ||
# rubocop:disable Style/AsciiComments | ||
# TODO: implement! | ||
|
@@ -43,14 +44,13 @@ def default_key_transform | |
|
||
# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure} | ||
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.} | ||
def serializable_hash(options = nil) | ||
options ||= {} | ||
def serializable_hash(_options = nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, we do need to take There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which options would they pass to Do you mean we should add |
||
document = if serializer.success? | ||
success_document(options) | ||
success_document | ||
else | ||
failure_document | ||
end | ||
transform_key_casing!(document, options[:serialization_context]) | ||
transform_key_casing!(document, instance_options[:serialization_context]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @groyoh So, there's no reason the adapter can't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand your comment. |
||
end | ||
|
||
# {http://jsonapi.org/format/#document-top-level Primary data} | ||
|
@@ -68,7 +68,7 @@ def serializable_hash(options = nil) | |
# links: toplevel_links, | ||
# jsonapi: toplevel_jsonapi | ||
# }.reject! {|_,v| v.nil? } | ||
def success_document(options) | ||
def success_document | ||
is_collection = serializer.respond_to?(:each) | ||
serializers = is_collection ? serializer : [serializer] | ||
primary_data, included = resource_objects_for(serializers) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,21 +21,19 @@ class PostSerializer < ActiveModel::Serializer | |
def setup | ||
ActionController::Base.cache_store.clear | ||
@blog = Blog.new(id: 1, name: 'My Blog!!', special_attribute: 'neat') | ||
serializer = CustomBlogSerializer.new(@blog) | ||
@adapter = ActiveModelSerializers::Adapter::Json.new(serializer) | ||
end | ||
|
||
def test_key_transform_default | ||
mock_request | ||
assert_equal({ | ||
blog: { id: 1, special_attribute: 'neat', articles: nil } | ||
}, @adapter.serializable_hash(@options)) | ||
}, adapter.serializable_hash) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
end | ||
|
||
def test_key_transform_global_config | ||
mock_request | ||
result = with_config(key_transform: :camel_lower) do | ||
@adapter.serializable_hash(@options) | ||
adapter.serializable_hash | ||
end | ||
assert_equal({ | ||
blog: { id: 1, specialAttribute: 'neat', articles: nil } | ||
|
@@ -45,7 +43,7 @@ def test_key_transform_global_config | |
def test_key_transform_serialization_ctx_overrides_global_config | ||
mock_request(:camel) | ||
result = with_config(key_transform: :camel_lower) do | ||
@adapter.serializable_hash(@options) | ||
adapter.serializable_hash | ||
end | ||
assert_equal({ | ||
Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil } | ||
|
@@ -56,36 +54,41 @@ def test_key_transform_undefined | |
mock_request(:blam) | ||
result = nil | ||
assert_raises NoMethodError do | ||
result = @adapter.serializable_hash(@options) | ||
result = adapter.serializable_hash | ||
end | ||
end | ||
|
||
def test_key_transform_dashed | ||
mock_request(:dashed) | ||
assert_equal({ | ||
blog: { id: 1, :"special-attribute" => 'neat', articles: nil } | ||
}, @adapter.serializable_hash(@options)) | ||
}, adapter.serializable_hash) | ||
end | ||
|
||
def test_key_transform_unaltered | ||
mock_request(:unaltered) | ||
assert_equal({ | ||
blog: { id: 1, special_attribute: 'neat', articles: nil } | ||
}, @adapter.serializable_hash(@options)) | ||
}, adapter.serializable_hash) | ||
end | ||
|
||
def test_key_transform_camel | ||
mock_request(:camel) | ||
assert_equal({ | ||
Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil } | ||
}, @adapter.serializable_hash(@options)) | ||
}, adapter.serializable_hash) | ||
end | ||
|
||
def test_key_transform_camel_lower | ||
mock_request(:camel_lower) | ||
assert_equal({ | ||
blog: { id: 1, specialAttribute: 'neat', articles: nil } | ||
}, @adapter.serializable_hash(@options)) | ||
}, adapter.serializable_hash) | ||
end | ||
|
||
def adapter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should just be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, I just move the call without thinking too much about it. Here I move the this part of the code in a method, to make sure that |
||
serializer = CustomBlogSerializer.new(@blog) | ||
ActiveModelSerializers::Adapter::Json.new(serializer, @options || {}) | ||
end | ||
end | ||
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.
I like the name change