Skip to content

Commit ca41901

Browse files
committed
Adjusts JsonApi adapter to serialize attributes in a nested attributes hash
1 parent 5f05944 commit ca41901

File tree

11 files changed

+148
-78
lines changed

11 files changed

+148
-78
lines changed

lib/active_model/serializer/adapter/json_api.rb

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,26 +85,31 @@ def attributes_for_serializer(serializer, options)
8585
if serializer.respond_to?(:each)
8686
result = []
8787
serializer.each do |object|
88-
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
89-
result << cache_check(object) do
90-
options[:required_fields] = [:id, :type]
91-
attributes = object.attributes(options)
92-
attributes[:id] = attributes[:id].to_s
93-
result << attributes
94-
end
88+
result << resource_object_for(object, options)
9589
end
9690
else
97-
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
98-
options[:required_fields] = [:id, :type]
99-
result = cache_check(serializer) do
100-
result = serializer.attributes(options)
101-
result[:id] = result[:id].to_s
102-
result
103-
end
91+
result = resource_object_for(serializer, options)
10492
end
10593
result
10694
end
10795

96+
def resource_object_for(serializer, options)
97+
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
98+
options[:required_fields] = [:id, :type]
99+
100+
cache_check(serializer) do
101+
attributes = serializer.attributes(options)
102+
103+
result = {
104+
id: attributes.delete(:id).to_s,
105+
type: attributes.delete(:type)
106+
}
107+
108+
result[:attributes] = attributes if attributes.any?
109+
result
110+
end
111+
end
112+
108113
def include_assoc?(assoc)
109114
return false unless @options[:include]
110115
check_assoc("#{assoc}$")

lib/active_model/serializer/adapter/json_api/fragment_cache.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ def fragment_cache(root, cached_hash, non_cached_hash)
1010
core_non_cached = non_cached_hash.first
1111
no_root_cache = cached_hash.delete_if {|key, value| key == core_cached[0] }
1212
no_root_non_cache = non_cached_hash.delete_if {|key, value| key == core_non_cached[0] }
13-
cached_resource = (core_cached[1]) ? core_cached[1].merge(core_non_cached[1]) : core_non_cached[1]
13+
cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
1414
hash = (root) ? { root => cached_resource } : cached_resource
15-
hash.merge no_root_non_cache.merge no_root_cache
15+
16+
hash.deep_merge no_root_non_cache.deep_merge no_root_cache
1617
end
1718

1819
end

test/action_controller/adapter_selector_test.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ def test_render_using_adapter_override
3232

3333
expected = {
3434
data: {
35-
name: "Name 1",
36-
description: "Description 1",
3735
id: assigns(:profile).id.to_s,
38-
type: "profiles"
36+
type: "profiles",
37+
attributes: {
38+
name: "Name 1",
39+
description: "Description 1",
40+
}
3941
}
4042
}
4143

test/action_controller/json_api_linked_test.rb

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def test_render_resource_with_include
9191
response = JSON.parse(@response.body)
9292
assert response.key? 'included'
9393
assert_equal 1, response['included'].size
94-
assert_equal 'Steve K.', response['included'].first['name']
94+
assert_equal 'Steve K.', response['included'].first['attributes']['name']
9595
end
9696

9797
def test_render_resource_with_nested_has_many_include
@@ -101,7 +101,9 @@ def test_render_resource_with_nested_has_many_include
101101
{
102102
"id" => "1",
103103
"type" => "authors",
104-
"name" => "Steve K.",
104+
"attributes" => {
105+
"name" => "Steve K."
106+
},
105107
"links" => {
106108
"posts" => { "linkage" => [] },
107109
"roles" => { "linkage" => [{ "type" =>"roles", "id" => "1" }, { "type" =>"roles", "id" => "2" }] },
@@ -110,18 +112,22 @@ def test_render_resource_with_nested_has_many_include
110112
}, {
111113
"id" => "1",
112114
"type" => "roles",
113-
"name" => "admin",
114-
"description" => nil,
115-
"slug" => "admin-1",
115+
"attributes" => {
116+
"name" => "admin",
117+
"description" => nil,
118+
"slug" => "admin-1"
119+
},
116120
"links" => {
117121
"author" => { "linkage" => { "type" =>"authors", "id" => "1" } }
118122
}
119123
}, {
120124
"id" => "2",
121125
"type" => "roles",
122-
"name" => "colab",
123-
"description" => nil,
124-
"slug" => "colab-2",
126+
"attributes" => {
127+
"name" => "colab",
128+
"description" => nil,
129+
"slug" => "colab-2"
130+
},
125131
"links" => {
126132
"author" => { "linkage" => { "type" =>"authors", "id" => "1" } }
127133
}
@@ -135,7 +141,7 @@ def test_render_resource_with_nested_include
135141
response = JSON.parse(@response.body)
136142
assert response.key? 'included'
137143
assert_equal 1, response['included'].size
138-
assert_equal 'Anonymous', response['included'].first['name']
144+
assert_equal 'Anonymous', response['included'].first['attributes']['name']
139145
end
140146

141147
def test_render_collection_without_include

test/action_controller/serialization_scope_name_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def render_new_user
2727

2828
def test_default_scope_name
2929
get :render_new_user
30-
assert_equal '{"data":{"admin?":false,"id":"1","type":"users"}}', @response.body
30+
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":false}}}', @response.body
3131
end
3232
end
3333

@@ -58,6 +58,6 @@ def render_new_user
5858

5959
def test_override_scope_name_with_controller
6060
get :render_new_user
61-
assert_equal '{"data":{"admin?":true,"id":"1","type":"users"}}', @response.body
61+
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":true}}}', @response.body
6262
end
6363
end

test/action_controller/serialization_test.rb

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,12 @@ def test_render_using_default_root
166166

167167
expected = {
168168
data: {
169-
name: "Name 1",
170-
description: "Description 1",
171169
id: assigns(:profile).id.to_s,
172-
type: "profiles"
170+
type: "profiles",
171+
attributes: {
172+
name: "Name 1",
173+
description: "Description 1"
174+
}
173175
}
174176
}
175177

@@ -182,10 +184,12 @@ def test_render_using_custom_root_in_adapter_with_a_default
182184

183185
expected = {
184186
data: {
185-
name: "Name 1",
186-
description: "Description 1",
187187
id: assigns(:profile).id.to_s,
188-
type: "profiles"
188+
type: "profiles",
189+
attributes: {
190+
name: "Name 1",
191+
description: "Description 1"
192+
}
189193
}
190194
}
191195

@@ -217,10 +221,12 @@ def test_render_array_using_implicit_serializer_and_meta
217221
expected = {
218222
data: [
219223
{
220-
name: "Name 1",
221-
description: "Description 1",
222224
id: assigns(:profiles).first.id.to_s,
223-
type: "profiles"
225+
type: "profiles",
226+
attributes: {
227+
name: "Name 1",
228+
description: "Description 1"
229+
}
224230
}
225231
],
226232
meta: {

test/adapter/json_api/belongs_to_test.rb

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ def test_includes_linked_post
4242
expected = [{
4343
id: "42",
4444
type: "posts",
45-
title: 'New Post',
46-
body: 'Body',
45+
attributes: {
46+
title: 'New Post',
47+
body: 'Body',
48+
},
4749
links: {
4850
comments: { linkage: [ { type: "comments", id: "1" } ] },
4951
blog: { linkage: { type: "blogs", id: "999" } },
@@ -58,7 +60,9 @@ def test_limiting_linked_post_fields
5860
expected = [{
5961
id: "42",
6062
type: "posts",
61-
title: 'New Post',
63+
attributes: {
64+
title: 'New Post'
65+
},
6266
links: {
6367
comments: { linkage: [ { type: "comments", id: "1" } ] },
6468
blog: { linkage: { type: "blogs", id: "999" } },
@@ -110,7 +114,9 @@ def test_include_linked_resources_with_type_name
110114
{
111115
id: "1",
112116
type: "authors",
113-
name: "Steve K.",
117+
attributes: {
118+
name: "Steve K."
119+
},
114120
links: {
115121
posts: { linkage: [] },
116122
roles: { linkage: [] },
@@ -119,8 +125,10 @@ def test_include_linked_resources_with_type_name
119125
},{
120126
id: "42",
121127
type: "posts",
122-
title: "New Post",
123-
body: "Body",
128+
attributes: {
129+
title: "New Post",
130+
body: "Body"
131+
},
124132
links: {
125133
comments: { linkage: [ { type: "comments", id: "1" } ] },
126134
blog: { linkage: { type: "blogs", id: "999" } },
@@ -129,8 +137,10 @@ def test_include_linked_resources_with_type_name
129137
}, {
130138
id: "43",
131139
type: "posts",
132-
title: "Hello!!",
133-
body: "Hello, world!!",
140+
attributes: {
141+
title: "Hello!!",
142+
body: "Hello, world!!"
143+
},
134144
links: {
135145
comments: { linkage: [] },
136146
blog: { linkage: { type: "blogs", id: "999" } },

test/adapter/json_api/collection_test.rb

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ def test_include_multiple_posts
2929
{
3030
id: "1",
3131
type: "posts",
32-
title: "Hello!!",
33-
body: "Hello, world!!",
32+
attributes: {
33+
title: "Hello!!",
34+
body: "Hello, world!!"
35+
},
3436
links: {
3537
comments: { linkage: [] },
3638
blog: { linkage: { type: "blogs", id: "999" } },
@@ -40,8 +42,10 @@ def test_include_multiple_posts
4042
{
4143
id: "2",
4244
type: "posts",
43-
title: "New Post",
44-
body: "Body",
45+
attributes: {
46+
title: "New Post",
47+
body: "Body"
48+
},
4549
links: {
4650
comments: { linkage: [] },
4751
blog: { linkage: { type: "blogs", id: "999" } },
@@ -60,7 +64,9 @@ def test_limiting_fields
6064
{
6165
id: "1",
6266
type: "posts",
63-
title: "Hello!!",
67+
attributes: {
68+
title: "Hello!!"
69+
},
6470
links: {
6571
comments: { linkage: [] },
6672
blog: { linkage: { type: "blogs", id: "999" } },
@@ -70,7 +76,9 @@ def test_limiting_fields
7076
{
7177
id: "2",
7278
type: "posts",
73-
title: "New Post",
79+
attributes: {
80+
title: "New Post"
81+
},
7482
links: {
7583
comments: { linkage: [] },
7684
blog: { linkage: { type: "blogs", id: "999" } },

test/adapter/json_api/has_many_test.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,19 @@ def test_includes_linked_comments
4343
expected = [{
4444
id: "1",
4545
type: "comments",
46-
body: 'ZOMG A COMMENT',
46+
attributes: {
47+
body: 'ZOMG A COMMENT'
48+
},
4749
links: {
4850
post: { linkage: { type: "posts", id: "1" } },
4951
author: { linkage: nil }
5052
}
5153
}, {
5254
id: "2",
5355
type: "comments",
54-
body: 'ZOMG ANOTHER COMMENT',
56+
attributes: {
57+
body: 'ZOMG ANOTHER COMMENT'
58+
},
5559
links: {
5660
post: { linkage: { type: "posts", id: "1" } },
5761
author: { linkage: nil }

test/adapter/json_api/has_one_test.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ def test_includes_linked_bio
4141
expected = [
4242
{
4343
id: "43",
44-
rating: nil,
4544
type: "bios",
46-
content:"AMS Contributor",
45+
attributes: {
46+
content:"AMS Contributor",
47+
rating: nil
48+
},
4749
links: {
4850
author: { linkage: { type: "authors", id: "1" } }
4951
}

0 commit comments

Comments
 (0)