Merge pull request #246 from beerlington/dry-option-setup

Refactor and consolidate serializer option setup
This commit is contained in:
Steve Klabnik 2013-03-20 08:56:54 -07:00
commit 680e2efbec
3 changed files with 42 additions and 49 deletions

View File

@ -51,31 +51,14 @@ module ActionController
end end
module RenderJsonOverride module RenderJsonOverride
def _render_option_json(json, options) def _render_option_json(resource, options)
options = default_serializer_options.merge(options) if default_serializer_options json = ActiveModel::Serializer.build_json(self, resource, options)
serializer = options.delete(:serializer) || if json
(json.respond_to?(:active_model_serializer) && json.active_model_serializer) super(json, options)
else
if json.respond_to?(:to_ary) super
unless serializer <= ActiveModel::ArraySerializer
raise ArgumentError.new("#{serializer.name} is not an ArraySerializer. " +
"You may want to use the :each_serializer option instead.")
end
if options[:root] != false && serializer.root != false
# default root element for arrays is serializer's root or the controller name
# the serializer for an Array is ActiveModel::ArraySerializer
options[:root] ||= serializer.root || controller_name
end
end end
if serializer
options[:scope] = serialization_scope unless options.has_key?(:scope)
options[:url_options] = url_options
json = serializer.new(json, options)
end
super
end end
end end

View File

@ -255,6 +255,39 @@ module ActiveModel
self._root = name self._root = name
end end
alias_method :root=, :root alias_method :root=, :root
# Used internally to create a new serializer object based on controller
# settings and options for a given resource. These settings are typically
# set during the request lifecycle or by the controller class, and should
# not be manually defined for this method.
def build_json(controller, resource, options)
default_options = controller.send(:default_serializer_options) || {}
options = default_options.merge(options || {})
serializer = options.delete(:serializer) ||
(resource.respond_to?(:active_model_serializer) &&
resource.active_model_serializer)
return serializer unless serializer
if resource.respond_to?(:to_ary)
unless serializer <= ActiveModel::ArraySerializer
raise ArgumentError.new("#{serializer.name} is not an ArraySerializer. " +
"You may want to use the :each_serializer option instead.")
end
if options[:root] != false && serializer.root != false
# the serializer for an Array is ActiveModel::ArraySerializer
options[:root] ||= serializer.root || controller.controller_name
end
end
options[:scope] = controller.serialization_scope unless options.has_key?(:scope)
options[:scope_name] = controller._serialization_scope
options[:url_options] = controller.url_options
serializer.new(resource, options)
end
end end
attr_reader :object, :options attr_reader :object, :options

View File

@ -1,39 +1,16 @@
module ActiveModel module ActiveModel
class Serializer class Serializer
class Responder < ::ActionController::Responder #:nodoc: class Responder < ::ActionController::Responder #:nodoc:
attr_reader :serializer
protected protected
def display(resource, given_options = {}) def display(resource, given_options = {})
if format != :json if format != :json
super super
else else
default_options = controller.send(:default_serializer_options) json = Serializer.build_json(controller, resource, options)
options = self.options.reverse_merge(default_options || {})
serializer = options[:serializer] || if json
(resource.respond_to?(:active_model_serializer) && render given_options.merge(options).merge(:json => json)
resource.active_model_serializer)
if resource.respond_to?(:to_ary)
unless serializer <= ActiveModel::ArraySerializer
raise ArgumentError.new("#{serializer.name} is not an ArraySerializer. " +
"You may want to use the :each_serializer option instead.")
end
if options[:root] != false && serializer.root != false
# default root element for arrays is serializer's root or the controller name
# the serializer for an Array is ActiveModel::ArraySerializer
options[:root] ||= serializer.root || controller.send(:controller_name)
end
end
if serializer
serialization_scope = controller.send(:serialization_scope)
options[:scope] = serialization_scope unless options.has_key?(:scope)
options[:scope_name] = controller.send(:_serialization_scope)
options[:url_options] = controller.send(:url_options)
render(given_options.merge(self.options).merge(:json => serializer.new(resource, options)))
else else
super super
end end