active_model_serializers 0.9.0 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +109 -17
- data/lib/action_controller/serialization.rb +27 -8
- data/lib/action_controller/serialization_test_case.rb +4 -4
- data/lib/active_model/array_serializer.rb +12 -5
- data/lib/active_model/serializable.rb +24 -2
- data/lib/active_model/serializable/utils.rb +16 -0
- data/lib/active_model/serializer.rb +70 -36
- data/lib/active_model/serializer/{associations.rb → association.rb} +8 -52
- data/lib/active_model/serializer/association/has_many.rb +39 -0
- data/lib/active_model/serializer/association/has_one.rb +25 -0
- data/lib/active_model/serializer/railtie.rb +8 -0
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +1 -1
- data/test/fixtures/poro.rb +106 -1
- data/test/fixtures/template.html.erb +1 -0
- data/test/integration/action_controller/namespaced_serialization_test.rb +96 -0
- data/test/integration/action_controller/serialization_test_case_test.rb +10 -0
- data/test/integration/active_record/active_record_test.rb +2 -2
- data/test/serializers/tmp/app/serializers/account_serializer.rb +3 -0
- data/test/test_app.rb +3 -0
- data/test/unit/active_model/array_serializer/serialization_test.rb +1 -1
- data/test/unit/active_model/serializer/associations/build_serializer_test.rb +15 -0
- data/test/unit/active_model/serializer/attributes_test.rb +16 -0
- data/test/unit/active_model/serializer/config_test.rb +3 -0
- data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +189 -0
- data/test/unit/active_model/serializer/has_many_test.rb +51 -16
- data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +27 -0
- data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +196 -0
- data/test/unit/active_model/serializer/has_one_test.rb +32 -0
- data/test/unit/active_model/serializer/options_test.rb +19 -0
- data/test/unit/active_model/serializer/url_helpers_test.rb +35 -0
- metadata +44 -27
@@ -11,6 +11,11 @@ module ActionController
|
|
11
11
|
def render_text
|
12
12
|
render text: 'ok'
|
13
13
|
end
|
14
|
+
|
15
|
+
def render_template
|
16
|
+
prepend_view_path "./test/fixtures"
|
17
|
+
render template: "template"
|
18
|
+
end
|
14
19
|
end
|
15
20
|
|
16
21
|
tests MyController
|
@@ -56,6 +61,11 @@ module ActionController
|
|
56
61
|
end
|
57
62
|
assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
|
58
63
|
end
|
64
|
+
|
65
|
+
def test_does_not_overwrite_notification_subscriptions
|
66
|
+
get :render_template
|
67
|
+
assert_template "template"
|
68
|
+
end
|
59
69
|
end
|
60
70
|
end
|
61
71
|
end
|
@@ -49,9 +49,9 @@ module ActiveModel
|
|
49
49
|
'ar_tag_ids' => [1, 2],
|
50
50
|
'ar_section_id' => 1
|
51
51
|
},
|
52
|
-
ar_comments
|
52
|
+
'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
|
53
53
|
{ body: 'i liked it', 'ar_tag_ids' => [3, 1] }],
|
54
|
-
ar_tags
|
54
|
+
'ar_tags' => [{ name: 'happy' }, { name: 'whiny' }, { name: 'short' }],
|
55
55
|
'ar_sections' => [{ 'name' => 'ruby' }]
|
56
56
|
}, post_serializer.as_json)
|
57
57
|
end
|
data/test/test_app.rb
CHANGED
@@ -3,6 +3,9 @@ class TestApp < Rails::Application
|
|
3
3
|
config.eager_load = false
|
4
4
|
config.secret_key_base = 'abc123'
|
5
5
|
end
|
6
|
+
config.after_initialize do
|
7
|
+
Rails.application.routes.default_url_options = { host: 'http://example.com' }
|
8
|
+
end
|
6
9
|
|
7
10
|
# Set up a logger to avoid creating a log directory on every run.
|
8
11
|
config.logger = Logger.new(nil)
|
@@ -85,7 +85,7 @@ module ActiveModel
|
|
85
85
|
{title: "Title 1", body: "Body 1", "comment_ids" => @post1.comments.map(&:object_id) },
|
86
86
|
{title: "Title 2", body: "Body 2", "comment_ids" => @post2.comments.map(&:object_id) }
|
87
87
|
],
|
88
|
-
comments
|
88
|
+
'comments' => [
|
89
89
|
{content: "C1"},
|
90
90
|
{content: "C2"},
|
91
91
|
{content: "C3"},
|
@@ -7,6 +7,7 @@ module ActiveModel
|
|
7
7
|
def setup
|
8
8
|
@association = Association::HasOne.new('post', serializer: PostSerializer)
|
9
9
|
@post = Post.new({ title: 'Title 1', body: 'Body 1', date: '1/1/2000' })
|
10
|
+
@user = User.new
|
10
11
|
end
|
11
12
|
|
12
13
|
def test_build_serializer_for_array_called_twice
|
@@ -15,6 +16,20 @@ module ActiveModel
|
|
15
16
|
assert_instance_of(PostSerializer, serializer)
|
16
17
|
end
|
17
18
|
end
|
19
|
+
|
20
|
+
def test_build_serializer_from_in_a_namespace
|
21
|
+
assoc = Association::HasOne.new('profile')
|
22
|
+
serializer = TestNamespace::UserSerializer.new(@user).build_serializer(assoc)
|
23
|
+
|
24
|
+
assert_instance_of(TestNamespace::ProfileSerializer, serializer)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_build_serializer_with_prefix
|
28
|
+
assoc = Association::HasOne.new('profile', prefix: :short)
|
29
|
+
serializer = UserSerializer.new(@user).build_serializer(assoc)
|
30
|
+
|
31
|
+
assert_instance_of(ShortProfileSerializer, serializer)
|
32
|
+
end
|
18
33
|
end
|
19
34
|
end
|
20
35
|
end
|
@@ -36,6 +36,22 @@ module ActiveModel
|
|
36
36
|
assert_equal([:name, :description],
|
37
37
|
another_inherited_serializer_klass._attributes)
|
38
38
|
end
|
39
|
+
|
40
|
+
def tests_query_attributes_strip_question_mark
|
41
|
+
model = Class.new(::Model) do
|
42
|
+
def strip?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
serializer = Class.new(ActiveModel::Serializer) do
|
48
|
+
attributes :strip?
|
49
|
+
end
|
50
|
+
|
51
|
+
actual = serializer.new(model.new).as_json
|
52
|
+
|
53
|
+
assert_equal({ strip: true }, actual)
|
54
|
+
end
|
39
55
|
end
|
40
56
|
end
|
41
57
|
end
|
@@ -78,6 +78,9 @@ module ActiveModel
|
|
78
78
|
assert !association.embed_objects?
|
79
79
|
assert association.embed_in_root
|
80
80
|
assert_equal :lower_camel, association.key_format
|
81
|
+
assert_equal 'post', PostSerializer.root_name
|
82
|
+
CONFIG.plural_default_root = true
|
83
|
+
assert_equal 'posts', PostSerializer.root_name
|
81
84
|
ensure
|
82
85
|
PostSerializer._associations[:comments] = old_association
|
83
86
|
CONFIG.clear
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
class Serializer
|
5
|
+
class HasManyPolymorphicTest < ActiveModel::TestCase
|
6
|
+
def setup
|
7
|
+
@association = MailSerializer._associations[:attachments]
|
8
|
+
@old_association = @association.dup
|
9
|
+
|
10
|
+
@mail = Mail.new({ body: 'Body 1' })
|
11
|
+
@mail_serializer = MailSerializer.new(@mail)
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
MailSerializer._associations[:attachments] = @old_association
|
16
|
+
end
|
17
|
+
|
18
|
+
def model_name(object)
|
19
|
+
object.class.to_s.demodulize.underscore.to_sym
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_associations_definition
|
23
|
+
assert_equal 1, MailSerializer._associations.length
|
24
|
+
assert_kind_of Association::HasMany, @association
|
25
|
+
assert_equal true, @association.polymorphic
|
26
|
+
assert_equal 'attachments', @association.name
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_associations_embedding_ids_serialization_using_serializable_hash
|
30
|
+
@association.embed = :ids
|
31
|
+
|
32
|
+
assert_equal({
|
33
|
+
body: 'Body 1',
|
34
|
+
'attachment_ids' => @mail.attachments.map do |c|
|
35
|
+
{ id: c.object_id, type: model_name(c) }
|
36
|
+
end
|
37
|
+
}, @mail_serializer.serializable_hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_associations_embedding_ids_serialization_using_as_json
|
41
|
+
@association.embed = :ids
|
42
|
+
|
43
|
+
assert_equal({
|
44
|
+
'mail' => {
|
45
|
+
:body => 'Body 1',
|
46
|
+
'attachment_ids' => @mail.attachments.map do |c|
|
47
|
+
{ id: c.object_id, type: model_name(c) }
|
48
|
+
end
|
49
|
+
}
|
50
|
+
}, @mail_serializer.as_json)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_associations_embedding_ids_serialization_using_serializable_hash_and_key_from_options
|
54
|
+
@association.embed = :ids
|
55
|
+
@association.key = 'key'
|
56
|
+
|
57
|
+
assert_equal({
|
58
|
+
body: 'Body 1',
|
59
|
+
'key' => @mail.attachments.map do |c|
|
60
|
+
{ id: c.object_id, type: model_name(c) }
|
61
|
+
end
|
62
|
+
}, @mail_serializer.serializable_hash)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_associations_embedding_objects_serialization_using_serializable_hash
|
66
|
+
@association.embed = :objects
|
67
|
+
|
68
|
+
assert_equal({
|
69
|
+
body: 'Body 1',
|
70
|
+
:attachments => [
|
71
|
+
{ type: :image, image: { url: 'U1' }},
|
72
|
+
{ type: :video, video: { html: 'H1' }}
|
73
|
+
]
|
74
|
+
}, @mail_serializer.serializable_hash)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_associations_embedding_objects_serialization_using_as_json
|
78
|
+
@association.embed = :objects
|
79
|
+
|
80
|
+
assert_equal({
|
81
|
+
'mail' => {
|
82
|
+
body: 'Body 1',
|
83
|
+
attachments: [
|
84
|
+
{ type: :image, image: { url: 'U1' }},
|
85
|
+
{ type: :video, video: { html: 'H1' }}
|
86
|
+
]
|
87
|
+
}
|
88
|
+
}, @mail_serializer.as_json)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_associations_embedding_nil_objects_serialization_using_as_json
|
92
|
+
@association.embed = :objects
|
93
|
+
@mail.instance_eval do
|
94
|
+
def attachments
|
95
|
+
[nil]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
assert_equal({
|
100
|
+
'mail' => {
|
101
|
+
:body => 'Body 1',
|
102
|
+
:attachments => [nil]
|
103
|
+
}
|
104
|
+
}, @mail_serializer.as_json)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options
|
108
|
+
@association.embed = :objects
|
109
|
+
@association.embedded_key = 'root'
|
110
|
+
|
111
|
+
assert_equal({
|
112
|
+
body: 'Body 1',
|
113
|
+
'root' => [
|
114
|
+
{ type: :image, image: { url: 'U1' }},
|
115
|
+
{ type: :video, video: { html: 'H1' }}
|
116
|
+
]
|
117
|
+
}, @mail_serializer.serializable_hash)
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_associations_embedding_ids_including_objects_serialization_using_serializable_hash
|
121
|
+
@association.embed = :ids
|
122
|
+
@association.embed_in_root = true
|
123
|
+
|
124
|
+
assert_equal({
|
125
|
+
body: 'Body 1',
|
126
|
+
'attachment_ids' => @mail.attachments.map do |c|
|
127
|
+
{ id: c.object_id, type: model_name(c) }
|
128
|
+
end
|
129
|
+
}, @mail_serializer.serializable_hash)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_associations_embedding_ids_including_objects_serialization_using_as_json
|
133
|
+
@association.embed = :ids
|
134
|
+
@association.embed_in_root = true
|
135
|
+
|
136
|
+
assert_equal({
|
137
|
+
'mail' => {
|
138
|
+
body: 'Body 1',
|
139
|
+
'attachment_ids' => @mail.attachments.map do |c|
|
140
|
+
{ id: c.object_id, type: model_name(c) }
|
141
|
+
end,
|
142
|
+
},
|
143
|
+
'attachments' => [
|
144
|
+
{ type: :image, image: { url: 'U1' }},
|
145
|
+
{ type: :video, video: { html: 'H1' }}
|
146
|
+
]
|
147
|
+
}, @mail_serializer.as_json)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_associations_embedding_nothing_including_objects_serialization_using_as_json
|
151
|
+
@association.embed = nil
|
152
|
+
@association.embed_in_root = true
|
153
|
+
|
154
|
+
assert_equal({
|
155
|
+
'mail' => { body: 'Body 1' },
|
156
|
+
'attachments' => [
|
157
|
+
{ type: :image, image: { url: 'U1' }},
|
158
|
+
{ type: :video, video: { html: 'H1' }}
|
159
|
+
]
|
160
|
+
}, @mail_serializer.as_json)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_associations_using_a_given_serializer
|
164
|
+
@association.embed = :ids
|
165
|
+
@association.embed_in_root = true
|
166
|
+
@association.serializer_from_options = Class.new(ActiveModel::Serializer) do
|
167
|
+
def fake
|
168
|
+
'fake'
|
169
|
+
end
|
170
|
+
|
171
|
+
attributes :fake
|
172
|
+
end
|
173
|
+
|
174
|
+
assert_equal({
|
175
|
+
'mail' => {
|
176
|
+
body: 'Body 1',
|
177
|
+
'attachment_ids' => @mail.attachments.map do |c|
|
178
|
+
{ id: c.object_id, type: model_name(c) }
|
179
|
+
end
|
180
|
+
},
|
181
|
+
'attachments' => [
|
182
|
+
{ type: :image, image: { fake: 'fake' }},
|
183
|
+
{ type: :video, video: { fake: 'fake' }}
|
184
|
+
]
|
185
|
+
}, @mail_serializer.as_json)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -111,17 +111,34 @@ module ActiveModel
|
|
111
111
|
|
112
112
|
assert_equal({
|
113
113
|
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
|
114
|
-
comments
|
114
|
+
'comments' => [{ content: 'C1' }, { content: 'C2' }]
|
115
115
|
}, @post_serializer.as_json)
|
116
116
|
end
|
117
117
|
|
118
|
+
def test_associations_embedding_ids_including_objects_serialization_when_invoked_from_parent_serializer
|
119
|
+
@association.embed = :ids
|
120
|
+
@association.embed_in_root = true
|
121
|
+
|
122
|
+
category = Category.new(name: 'Name 1')
|
123
|
+
category.instance_variable_set(:@posts, [@post])
|
124
|
+
category_serializer = CategorySerializer.new(category)
|
125
|
+
|
126
|
+
assert_equal({
|
127
|
+
'category' => {
|
128
|
+
name: 'Name 1',
|
129
|
+
posts: [{ title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } }]
|
130
|
+
},
|
131
|
+
"comments" => [{ content: 'C1' }, { content: 'C2' }]
|
132
|
+
}, category_serializer.as_json)
|
133
|
+
end
|
134
|
+
|
118
135
|
def test_associations_embedding_nothing_including_objects_serialization_using_as_json
|
119
136
|
@association.embed = nil
|
120
137
|
@association.embed_in_root = true
|
121
138
|
|
122
139
|
assert_equal({
|
123
140
|
'post' => { title: 'Title 1', body: 'Body 1' },
|
124
|
-
comments
|
141
|
+
'comments' => [{ content: 'C1' }, { content: 'C2' }]
|
125
142
|
}, @post_serializer.as_json)
|
126
143
|
end
|
127
144
|
|
@@ -138,7 +155,7 @@ module ActiveModel
|
|
138
155
|
|
139
156
|
assert_equal({
|
140
157
|
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
|
141
|
-
comments
|
158
|
+
'comments' => [{ content: 'C1!' }, { content: 'C2!' }]
|
142
159
|
}, @post_serializer.as_json)
|
143
160
|
end
|
144
161
|
|
@@ -153,7 +170,7 @@ module ActiveModel
|
|
153
170
|
|
154
171
|
assert_equal({
|
155
172
|
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
|
156
|
-
comments
|
173
|
+
'comments' => { my_content: ['fake'] }
|
157
174
|
}, @post_serializer.as_json)
|
158
175
|
end
|
159
176
|
|
@@ -174,16 +191,16 @@ module ActiveModel
|
|
174
191
|
@association.embed_in_root_key = :linked
|
175
192
|
@association.embed = :ids
|
176
193
|
assert_equal({
|
194
|
+
'post' => {
|
195
|
+
title: 'Title 1', body: 'Body 1',
|
196
|
+
'comment_ids' => @post.comments.map(&:object_id)
|
197
|
+
},
|
177
198
|
linked: {
|
178
|
-
comments
|
199
|
+
'comments' => [
|
179
200
|
{ content: 'C1' },
|
180
201
|
{ content: 'C2' }
|
181
202
|
]
|
182
203
|
},
|
183
|
-
'post' => {
|
184
|
-
title: 'Title 1', body: 'Body 1',
|
185
|
-
'comment_ids' => @post.comments.map(&:object_id)
|
186
|
-
}
|
187
204
|
}, @post_serializer.as_json)
|
188
205
|
end
|
189
206
|
|
@@ -194,18 +211,18 @@ module ActiveModel
|
|
194
211
|
@association.embed_namespace = :links
|
195
212
|
@association.key = :comments
|
196
213
|
assert_equal({
|
197
|
-
linked: {
|
198
|
-
comments: [
|
199
|
-
{ content: 'C1' },
|
200
|
-
{ content: 'C2' }
|
201
|
-
]
|
202
|
-
},
|
203
214
|
'post' => {
|
204
215
|
title: 'Title 1', body: 'Body 1',
|
205
216
|
links: {
|
206
217
|
comments: @post.comments.map(&:object_id)
|
207
218
|
}
|
208
|
-
}
|
219
|
+
},
|
220
|
+
linked: {
|
221
|
+
'comments' => [
|
222
|
+
{ content: 'C1' },
|
223
|
+
{ content: 'C2' }
|
224
|
+
]
|
225
|
+
},
|
209
226
|
}, @post_serializer.as_json)
|
210
227
|
end
|
211
228
|
|
@@ -225,6 +242,24 @@ module ActiveModel
|
|
225
242
|
}
|
226
243
|
}, @post_serializer.as_json)
|
227
244
|
end
|
245
|
+
|
246
|
+
def test_associations_name_key_embedding_ids_serialization_using_serializable_hash
|
247
|
+
@association = NameKeyPostSerializer._associations[:comments]
|
248
|
+
@association.embed = :ids
|
249
|
+
|
250
|
+
assert_equal({
|
251
|
+
title: 'Title 1', body: 'Body 1', 'comments' => @post.comments.map { |c| c.object_id }
|
252
|
+
}, NameKeyPostSerializer.new(@post).serializable_hash)
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_associations_name_key_embedding_ids_serialization_using_as_json
|
256
|
+
@association = NameKeyPostSerializer._associations[:comments]
|
257
|
+
@association.embed = :ids
|
258
|
+
|
259
|
+
assert_equal({
|
260
|
+
'name_key_post' => { title: 'Title 1', body: 'Body 1', 'comments' => @post.comments.map { |c| c.object_id } }
|
261
|
+
}, NameKeyPostSerializer.new(@post).as_json)
|
262
|
+
end
|
228
263
|
end
|
229
264
|
end
|
230
265
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
class Serializer
|
5
|
+
class HasOneAndHasManyTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@post = SpecialPost.new({ title: 'T1', body: 'B1'})
|
8
|
+
@post_serializer = SpecialPostSerializer.new(@post)
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_side_load_has_one_and_has_many_in_same_array
|
15
|
+
assert_equal({
|
16
|
+
"post" => {
|
17
|
+
title: 'T1',
|
18
|
+
body: 'B1',
|
19
|
+
'comment_ids' => @post.comments.map { |c| c.object_id },
|
20
|
+
'special_comment_id' => @post_serializer.special_comment.object_id,
|
21
|
+
},
|
22
|
+
"comments" => [{ content: 'C1' }, { content: 'C2' }, { content: 'special' }]
|
23
|
+
}, @post_serializer.as_json(root: 'post'))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|