Skip to content

Commit 7066b1f

Browse files
committed
Merge pull request #1013 from vyrak/root-option
Root option with empty array support
2 parents 357d0d4 + 1b09d0e commit 7066b1f

File tree

5 files changed

+121
-21
lines changed

5 files changed

+121
-21
lines changed

lib/active_model/serializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def initialize(object, options = {})
169169
end
170170

171171
def json_key
172-
self.class.root_name
172+
@root || self.class.root_name
173173
end
174174

175175
def id

lib/active_model/serializer/array_serializer.rb

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ class ArraySerializer
55
include Enumerable
66
delegate :each, to: :@objects
77

8-
attr_reader :meta, :meta_key
8+
attr_reader :root, :meta, :meta_key
99

1010
def initialize(objects, options = {})
11+
@root = options[:root]
1112
@resource = objects
1213
@objects = objects.map do |object|
1314
serializer_class = options.fetch(
@@ -26,15 +27,8 @@ def initialize(objects, options = {})
2627
end
2728

2829
def json_key
29-
if @objects.first
30-
@objects.first.json_key.pluralize
31-
else
32-
@resource.name.underscore.pluralize if @resource.try(:name)
33-
end
34-
end
35-
36-
def root=(root)
37-
@objects.first.root = root if @objects.first
30+
key = root || @objects.first.try(:json_key) || @resource.try(:name).try(:underscore)
31+
key.try(:pluralize)
3832
end
3933
end
4034
end

test/action_controller/serialization_test.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,26 @@ def render_using_default_adapter_root
1818
end
1919
end
2020

21+
def render_array_using_custom_root
22+
with_adapter ActiveModel::Serializer::Adapter::Json do
23+
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
24+
render json: [@profile], root: "custom_root"
25+
end
26+
end
27+
28+
def render_array_that_is_empty_using_custom_root
29+
with_adapter ActiveModel::Serializer::Adapter::Json do
30+
render json: [], root: "custom_root"
31+
end
32+
end
33+
34+
def render_object_using_custom_root
35+
with_adapter ActiveModel::Serializer::Adapter::Json do
36+
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
37+
render json: @profile, root: "custom_root"
38+
end
39+
end
40+
2141
def render_array_using_implicit_serializer
2242
array = [
2343
Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
@@ -169,6 +189,30 @@ def test_render_using_default_root
169189
assert_equal expected.to_json, @response.body
170190
end
171191

192+
def test_render_array_using_custom_root
193+
get :render_array_using_custom_root
194+
195+
expected = {custom_roots: [{name: "Name 1", description: "Description 1"}]}
196+
assert_equal 'application/json', @response.content_type
197+
assert_equal expected.to_json, @response.body
198+
end
199+
200+
def test_render_array_that_is_empty_using_custom_root
201+
get :render_array_that_is_empty_using_custom_root
202+
203+
expected = {custom_roots: []}
204+
assert_equal 'application/json', @response.content_type
205+
assert_equal expected.to_json, @response.body
206+
end
207+
208+
def test_render_object_using_custom_root
209+
get :render_object_using_custom_root
210+
211+
expected = {custom_root: {name: "Name 1", description: "Description 1"}}
212+
assert_equal 'application/json', @response.content_type
213+
assert_equal expected.to_json, @response.body
214+
end
215+
172216
def test_render_json_object_without_serializer
173217
get :render_json_object_without_serializer
174218

test/array_serializer_test.rb

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ class ArraySerializerTest < Minitest::Test
66
def setup
77
@comment = Comment.new
88
@post = Post.new
9-
@serializer = ArraySerializer.new([@comment, @post], {some: :options})
9+
@resource = build_named_collection @comment, @post
10+
@serializer = ArraySerializer.new(@resource, {some: :options})
11+
end
12+
13+
def build_named_collection(*resource)
14+
resource.define_singleton_method(:name){ 'MeResource' }
15+
resource
1016
end
1117

1218
def test_respond_to_each
@@ -39,15 +45,52 @@ def test_meta_and_meta_key_attr_readers
3945
assert_equal @serializer.meta_key, "the meta key"
4046
end
4147

42-
def test_json_key_when_resource_is_empty
43-
Array.class_eval do
44-
def name
45-
'PostComment'
46-
end
47-
end
48-
@post_comments = []
49-
@serializer = ArraySerializer.new(@post_comments)
50-
assert_equal @serializer.json_key, "post_comments"
48+
def test_root_default
49+
@serializer = ArraySerializer.new([@comment, @post])
50+
assert_equal @serializer.root, nil
51+
end
52+
53+
def test_root
54+
expected = 'custom_root'
55+
@serializer = ArraySerializer.new([@comment, @post], root: expected)
56+
assert_equal @serializer.root, expected
57+
end
58+
59+
def test_root_with_no_serializers
60+
expected = 'custom_root'
61+
@serializer = ArraySerializer.new([], root: expected)
62+
assert_equal @serializer.root, expected
63+
end
64+
65+
def test_json_key
66+
assert_equal @serializer.json_key, 'comments'
67+
end
68+
69+
def test_json_key_with_resource_with_name_and_no_serializers
70+
serializer = ArraySerializer.new(build_named_collection)
71+
assert_equal serializer.json_key, 'me_resources'
72+
end
73+
74+
def test_json_key_with_resource_with_nil_name_and_no_serializers
75+
resource = []
76+
resource.define_singleton_method(:name){ nil }
77+
serializer = ArraySerializer.new(resource)
78+
assert_equal serializer.json_key, nil
79+
end
80+
81+
def test_json_key_with_resource_without_name_and_no_serializers
82+
serializer = ArraySerializer.new([])
83+
assert_equal serializer.json_key, nil
84+
end
85+
86+
def test_json_key_with_root
87+
serializer = ArraySerializer.new(@resource, root: 'custom_root')
88+
assert_equal serializer.json_key, 'custom_roots'
89+
end
90+
91+
def test_json_key_with_root_and_no_serializers
92+
serializer = ArraySerializer.new(build_named_collection, root: 'custom_root')
93+
assert_equal serializer.json_key, 'custom_roots'
5194
end
5295
end
5396
end

test/serializers/root_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'test_helper'
2+
3+
module ActiveModel
4+
class Serializer
5+
class RootTest < Minitest::Test
6+
7+
def setup
8+
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
9+
@profile_serializer = ProfileSerializer.new(@post, {root: 'smth'})
10+
end
11+
12+
def test_overwrite_root
13+
setup
14+
assert_equal('smth', @profile_serializer.json_key)
15+
end
16+
17+
end
18+
end
19+
end

0 commit comments

Comments
 (0)