active_model_serializers 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +109 -17
  4. data/lib/action_controller/serialization.rb +27 -8
  5. data/lib/action_controller/serialization_test_case.rb +4 -4
  6. data/lib/active_model/array_serializer.rb +12 -5
  7. data/lib/active_model/serializable.rb +24 -2
  8. data/lib/active_model/serializable/utils.rb +16 -0
  9. data/lib/active_model/serializer.rb +70 -36
  10. data/lib/active_model/serializer/{associations.rb → association.rb} +8 -52
  11. data/lib/active_model/serializer/association/has_many.rb +39 -0
  12. data/lib/active_model/serializer/association/has_one.rb +25 -0
  13. data/lib/active_model/serializer/railtie.rb +8 -0
  14. data/lib/active_model/serializer/version.rb +1 -1
  15. data/lib/active_model_serializers.rb +1 -1
  16. data/test/fixtures/poro.rb +106 -1
  17. data/test/fixtures/template.html.erb +1 -0
  18. data/test/integration/action_controller/namespaced_serialization_test.rb +96 -0
  19. data/test/integration/action_controller/serialization_test_case_test.rb +10 -0
  20. data/test/integration/active_record/active_record_test.rb +2 -2
  21. data/test/serializers/tmp/app/serializers/account_serializer.rb +3 -0
  22. data/test/test_app.rb +3 -0
  23. data/test/unit/active_model/array_serializer/serialization_test.rb +1 -1
  24. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +15 -0
  25. data/test/unit/active_model/serializer/attributes_test.rb +16 -0
  26. data/test/unit/active_model/serializer/config_test.rb +3 -0
  27. data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +189 -0
  28. data/test/unit/active_model/serializer/has_many_test.rb +51 -16
  29. data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +27 -0
  30. data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +196 -0
  31. data/test/unit/active_model/serializer/has_one_test.rb +32 -0
  32. data/test/unit/active_model/serializer/options_test.rb +19 -0
  33. data/test/unit/active_model/serializer/url_helpers_test.rb +35 -0
  34. metadata +38 -23
  35. data/test/tmp/app/serializers/account_serializer.rb +0 -3
@@ -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: [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
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: [{ name: 'happy' }, { name: 'whiny' }, { name: 'short' }],
54
+ 'ar_tags' => [{ name: 'happy' }, { name: 'whiny' }, { name: 'short' }],
55
55
  'ar_sections' => [{ 'name' => 'ruby' }]
56
56
  }, post_serializer.as_json)
57
57
  end
@@ -0,0 +1,3 @@
1
+ class AccountSerializer < ActiveModel::Serializer
2
+ attributes :id
3
+ end
@@ -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: [{ content: 'C1' }, { content: 'C2' }]
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: [{ content: 'C1' }, { content: 'C2' }]
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: [{ content: 'C1!' }, { content: 'C2!' }]
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: { my_content: ['fake'] }
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