Skip to content

Commit

Permalink
Prevent controller options from being mutated
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
bf4 authored and Yohan Robert committed Mar 19, 2016
1 parent 61412d8 commit f436ab9
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 437 deletions.
17 changes: 11 additions & 6 deletions lib/action_controller/serialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ def serialization_scope
respond_to?(_serialization_scope, true)
end

def get_serializer(resource, 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"
options[:adapter] = false
serialization_options[:adapter] = false
end
serializable_resource = ActiveModel::SerializableResource.new(resource, 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
Expand All @@ -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
if options.key?(:serializer)
serialization_options[:serializer] = options[:serializer]
end
serializable_resource = get_serializer(resource, options)
unless serialization_options.key?(:serialization_context)
serialization_options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, serialization_options)
end
serializable_resource = get_serializer(resource, serialization_options)
super(serializable_resource, options)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/active_model/serializable_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
include ActiveModelSerializers::Logging

delegate :serializable_hash, :as_json, :to_json, to: :adapter
Expand Down
2 changes: 1 addition & 1 deletion lib/active_model_serializers/adapter/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Json < Base
def serializable_hash(options = nil)
options ||= {}
serialized_hash = { root => Attributes.new(serializer, instance_options).serializable_hash(options) }
transform_key_casing!(serialized_hash, options[:serialization_context])
transform_key_casing!(serialized_hash, instance_options[:serialization_context])
end
end
end
Expand Down
16 changes: 8 additions & 8 deletions lib/active_model_serializers/adapter/json_api.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# coding: utf-8
# {http://jsonapi.org/format/ JSON API specification}
# rubocop:disable Style/AsciiComments
# TODO: implement!
Expand Down Expand Up @@ -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)
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])
end

# {http://jsonapi.org/format/#document-top-level Primary data}
Expand All @@ -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)
Expand Down Expand Up @@ -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

hash
Expand Down Expand Up @@ -498,8 +498,8 @@ def links_for(serializer)
# end
# prs:
# https://github.com/rails-api/active_model_serializers/pull/1041
def pagination_links_for(serializer, options)
PaginationLinks.new(serializer.object, options[:serialization_context]).serializable_hash(options)
def pagination_links_for(serializer)
PaginationLinks.new(serializer.object, instance_options[:serialization_context]).as_json(instance_options)
end

# {http://jsonapi.org/format/#document-meta Docment Meta}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def initialize(collection, context)
@context = context
end

def serializable_hash(options = {})
def as_json(options = {})
per_page = collection.try(:per_page) || collection.try(:limit_value) || collection.size
pages_from.each_with_object({}) do |(key, value), hash|
params = query_parameters.merge(page: { number: value, size: per_page }).to_query
Expand Down
23 changes: 13 additions & 10 deletions test/adapter/json/key_case_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
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 }
Expand All @@ -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 }
Expand All @@ -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
serializer = CustomBlogSerializer.new(@blog)
ActiveModelSerializers::Adapter::Json.new(serializer, @options || {})
end
end
end
Expand Down
Loading

0 comments on commit f436ab9

Please sign in to comment.