diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb index 4230e1d0..d52c6800 100644 --- a/lib/action_controller/serialization.rb +++ b/lib/action_controller/serialization.rb @@ -40,13 +40,17 @@ module ActionController end def _render_option_json(json, options) - if json.respond_to?(:to_ary) - options[:root] ||= controller_name unless options[:root] == false - end - serializer = options.delete(:serializer) || (json.respond_to?(:active_model_serializer) && json.active_model_serializer) + if json.respond_to?(:to_ary) + 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 + if serializer options[:scope] = serialization_scope options[:url_options] = url_options diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 32dbe2e9..cb5b25ef 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -29,11 +29,18 @@ module ActiveModel # Active Model Array Serializer # - # It serializes an array checking if each element that implements + # It serializes an Array, checking if each element that implements # the +active_model_serializer+ method. + # + # To disable serialization of root elements, in an initializer: + # + # ActiveModel::ArraySerializer.root = false + # class ArraySerializer attr_reader :object, :options + class_attribute :root + def initialize(object, options={}) @object, @options = object, options end diff --git a/test/serialization_test.rb b/test/serialization_test.rb index d382f2ce..9706f70a 100644 --- a/test/serialization_test.rb +++ b/test/serialization_test.rb @@ -66,6 +66,10 @@ class RenderJsonTest < ActionController::TestCase end end + class CustomArraySerializer < ActiveModel::ArraySerializer + self.root = "items" + end + class TestController < ActionController::Base protect_from_forgery @@ -132,8 +136,14 @@ class RenderJsonTest < ActionController::TestCase render :json => JsonSerializable.new(true) end + # To specify a custom serializer for an object, use :serializer. def render_json_with_custom_serializer - render :json => [], :serializer => CustomSerializer + render :json => Object.new, :serializer => CustomSerializer + end + + # To specify a custom serializer for each item in the Array, use :each_serializer. + def render_json_array_with_custom_serializer + render :json => [Object.new], :each_serializer => CustomSerializer end def render_json_with_links @@ -144,6 +154,14 @@ class RenderJsonTest < ActionController::TestCase render :json => [], :root => false end + def render_json_empty_array + render :json => [] + end + + def render_json_array_with_custom_array_serializer + render :json => [], :serializer => CustomArraySerializer + end + private def default_serializer_options @@ -251,6 +269,11 @@ class RenderJsonTest < ActionController::TestCase assert_match '{"hello":true}', @response.body end + def test_render_json_array_with_custom_serializer + get :render_json_array_with_custom_serializer + assert_match '{"test":[{"hello":true}]}', @response.body + end + def test_render_json_with_links get :render_json_with_links assert_match '{"link":"http://www.nextangle.com/hypermedia"}', @response.body @@ -260,4 +283,23 @@ class RenderJsonTest < ActionController::TestCase get :render_json_array_with_no_root assert_equal '[]', @response.body end + + def test_render_json_empty_array + get :render_json_empty_array + assert_equal '{"test":[]}', @response.body + end + + def test_render_json_empty_arry_with_array_serializer_root_false + ActiveModel::ArraySerializer.root = false + get :render_json_empty_array + assert_equal '[]', @response.body + ensure # teardown + ActiveModel::ArraySerializer.root = nil + end + + def test_render_json_array_with_custom_array_serializer + get :render_json_array_with_custom_array_serializer + assert_equal '{"items":[]}', @response.body + end + end