From fd578fcf69abf687113a546f42fcb246c464743e Mon Sep 17 00:00:00 2001 From: beerlington Date: Sun, 17 Mar 2013 18:01:43 -0400 Subject: [PATCH] Refactor and consolidate serializer option setup --- lib/action_controller/serialization.rb | 29 +++++------------------- lib/active_model/serializer.rb | 29 ++++++++++++++++++++++++ lib/active_model/serializer/responder.rb | 29 +++--------------------- 3 files changed, 38 insertions(+), 49 deletions(-) diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb index 80c2b814..0908d6ed 100644 --- a/lib/action_controller/serialization.rb +++ b/lib/action_controller/serialization.rb @@ -51,31 +51,14 @@ module ActionController end module RenderJsonOverride - def _render_option_json(json, options) - options = default_serializer_options.merge(options) if default_serializer_options + def _render_option_json(resource, options) + json = ActiveModel::Serializer.build_json(self, resource, options) - serializer = options.delete(:serializer) || - (json.respond_to?(:active_model_serializer) && json.active_model_serializer) - - if json.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_name - end + if json + super(json, options) + else + super 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 diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 7f397a06..7b562298 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -255,6 +255,35 @@ module ActiveModel self._root = name end alias_method :root=, :root + + 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 attr_reader :object, :options diff --git a/lib/active_model/serializer/responder.rb b/lib/active_model/serializer/responder.rb index 46a1d91f..eeb6d7dd 100644 --- a/lib/active_model/serializer/responder.rb +++ b/lib/active_model/serializer/responder.rb @@ -1,39 +1,16 @@ module ActiveModel class Serializer class Responder < ::ActionController::Responder #:nodoc: - attr_reader :serializer protected def display(resource, given_options = {}) if format != :json super else - default_options = controller.send(:default_serializer_options) - options = self.options.reverse_merge(default_options || {}) + json = Serializer.build_json(controller, resource, options) - serializer = options[:serializer] || - (resource.respond_to?(:active_model_serializer) && - 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))) + if json + render given_options.merge(options).merge(:json => json) else super end