From 0832e4291736f652d296f1387a6891557fc8f8b0 Mon Sep 17 00:00:00 2001 From: Tee Parham Date: Sat, 14 Jul 2012 21:44:23 -0600 Subject: [PATCH 1/2] add class attribute :root to ArraySerializer You can now set the default behavior for Array serialization in a single place --- lib/action_controller/serialization.rb | 12 ++++++---- lib/active_model/serializer.rb | 9 +++++++- test/serialization_test.rb | 31 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) 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 b2eac4ee..6868369a 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..3e7d72ad 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 @@ -144,6 +148,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 @@ -260,4 +272,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 From 84c7cfa988b9c65d6d05f7aa3ed817ed96c625d2 Mon Sep 17 00:00:00 2001 From: Tee Parham Date: Sat, 14 Jul 2012 22:03:14 -0600 Subject: [PATCH 2/2] fix test for custom serializer, add test for :each_serializer --- test/serialization_test.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/serialization_test.rb b/test/serialization_test.rb index 3e7d72ad..9706f70a 100644 --- a/test/serialization_test.rb +++ b/test/serialization_test.rb @@ -136,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 @@ -263,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