active_model_serializers 0.9.0 → 0.9.8

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.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +113 -0
  3. data/README.md +112 -19
  4. data/lib/action_controller/serialization.rb +35 -8
  5. data/lib/action_controller/serialization_test_case.rb +4 -4
  6. data/lib/active_model/array_serializer.rb +13 -10
  7. data/lib/active_model/default_serializer.rb +2 -6
  8. data/lib/active_model/serializable.rb +30 -11
  9. data/lib/active_model/serializable/utils.rb +16 -0
  10. data/lib/active_model/serializer.rb +90 -40
  11. data/lib/active_model/serializer/{associations.rb → association.rb} +8 -52
  12. data/lib/active_model/serializer/association/has_many.rb +39 -0
  13. data/lib/active_model/serializer/association/has_one.rb +25 -0
  14. data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +1 -1
  15. data/lib/active_model/serializer/railtie.rb +12 -0
  16. data/lib/active_model/serializer/version.rb +1 -1
  17. data/lib/active_model_serializers.rb +1 -1
  18. data/lib/active_model_serializers/model/caching.rb +25 -0
  19. data/test/benchmark/app.rb +60 -0
  20. data/test/benchmark/benchmarking_support.rb +67 -0
  21. data/test/benchmark/bm_active_record.rb +41 -0
  22. data/test/benchmark/setup.rb +75 -0
  23. data/test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25 +0 -0
  24. data/test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0 +0 -0
  25. data/test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c +0 -0
  26. data/test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48 +0 -0
  27. data/test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3 +0 -0
  28. data/test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0 +0 -0
  29. data/test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i +0 -0
  30. data/test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790 +0 -0
  31. data/test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj +0 -0
  32. data/test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1 +0 -0
  33. data/test/fixtures/active_record.rb +4 -0
  34. data/test/fixtures/poro.rb +149 -1
  35. data/test/fixtures/template.html.erb +1 -0
  36. data/test/integration/action_controller/namespaced_serialization_test.rb +105 -0
  37. data/test/integration/action_controller/serialization_test.rb +5 -5
  38. data/test/integration/action_controller/serialization_test_case_test.rb +10 -0
  39. data/test/integration/active_record/active_record_test.rb +19 -2
  40. data/test/test_app.rb +3 -0
  41. data/test/tmp/app/assets/javascripts/accounts.js +2 -0
  42. data/test/tmp/app/assets/stylesheets/accounts.css +4 -0
  43. data/test/tmp/app/controllers/accounts_controller.rb +2 -0
  44. data/test/tmp/app/helpers/accounts_helper.rb +2 -0
  45. data/test/tmp/app/serializers/account_serializer.rb +3 -0
  46. data/test/tmp/config/routes.rb +1 -0
  47. data/test/unit/active_model/array_serializer/options_test.rb +16 -0
  48. data/test/unit/active_model/array_serializer/serialization_test.rb +18 -1
  49. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +15 -0
  50. data/test/unit/active_model/serializer/associations_test.rb +30 -0
  51. data/test/unit/active_model/serializer/attributes_test.rb +16 -0
  52. data/test/unit/active_model/serializer/config_test.rb +3 -0
  53. data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +189 -0
  54. data/test/unit/active_model/serializer/has_many_test.rb +52 -17
  55. data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +27 -0
  56. data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +196 -0
  57. data/test/unit/active_model/serializer/has_one_test.rb +46 -0
  58. data/test/unit/active_model/serializer/options_test.rb +27 -0
  59. data/test/unit/active_model/serializer/url_helpers_test.rb +35 -0
  60. data/test/unit/active_model/serilizable_test.rb +50 -0
  61. metadata +98 -25
@@ -0,0 +1 @@
1
+ <p>Hello.</p>
@@ -0,0 +1,105 @@
1
+ require 'test_helper'
2
+
3
+ module ActionController
4
+ module Serialization
5
+ class NamespacedSerializationTest < ActionController::TestCase
6
+ class TestNamespace::MyController < ActionController::Base
7
+ def render_profile_with_namespace
8
+ render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
9
+ end
10
+
11
+ def render_profiles_with_namespace
12
+ render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
13
+ end
14
+
15
+ def render_comment
16
+ render json: Comment.new(content: 'Comment 1')
17
+ end
18
+
19
+ def render_comments
20
+ render json: [Comment.new(content: 'Comment 1')]
21
+ end
22
+
23
+ def render_hash
24
+ render json: {message: 'not found'}, status: 404
25
+ end
26
+ end
27
+
28
+ tests TestNamespace::MyController
29
+
30
+ def test_render_profile_with_namespace
31
+ get :render_profile_with_namespace
32
+ assert_serializer TestNamespace::ProfileSerializer
33
+ end
34
+
35
+ def test_render_profiles_with_namespace
36
+ get :render_profiles_with_namespace
37
+ assert_serializer TestNamespace::ProfileSerializer
38
+ end
39
+
40
+ def test_fallback_to_a_version_without_namespace
41
+ get :render_comment
42
+ assert_serializer CommentSerializer
43
+ end
44
+
45
+ def test_array_fallback_to_a_version_without_namespace
46
+ get :render_comments
47
+ assert_serializer CommentSerializer
48
+ end
49
+
50
+ def test_render_hash_regression
51
+ get :render_hash
52
+ assert_equal JSON.parse(response.body), {'message' => 'not found'}
53
+ end
54
+ end
55
+
56
+ class OptionNamespacedSerializationTest < ActionController::TestCase
57
+ class MyController < ActionController::Base
58
+ def default_serializer_options
59
+ {
60
+ namespace: TestNamespace
61
+ }
62
+ end
63
+
64
+ def render_profile_with_namespace_option
65
+ render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
66
+ end
67
+
68
+ def render_profiles_with_namespace_option
69
+ render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
70
+ end
71
+
72
+ def render_comment
73
+ render json: Comment.new(content: 'Comment 1')
74
+ end
75
+
76
+ def render_comments
77
+ render json: [Comment.new(content: 'Comment 1')]
78
+ end
79
+ end
80
+
81
+ tests MyController
82
+
83
+ def test_render_profile_with_namespace_option
84
+ get :render_profile_with_namespace_option
85
+ assert_serializer TestNamespace::ProfileSerializer
86
+ end
87
+
88
+ def test_render_profiles_with_namespace_option
89
+ get :render_profiles_with_namespace_option
90
+ assert_serializer TestNamespace::ProfileSerializer
91
+ end
92
+
93
+ def test_fallback_to_a_version_without_namespace
94
+ get :render_comment
95
+ assert_serializer CommentSerializer
96
+ end
97
+
98
+ def test_array_fallback_to_a_version_without_namespace
99
+ get :render_comments
100
+ assert_serializer CommentSerializer
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -213,8 +213,8 @@ module ActionController
213
213
  class LowerCamelWoRootSerializerTest < ActionController::TestCase
214
214
  class WebLogController < ActionController::Base
215
215
  def render_without_root
216
- render json: WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
217
- root: false,
216
+ render json: WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
217
+ root: false,
218
218
  serializer: WebLogLowerCamelSerializer
219
219
  end
220
220
  end
@@ -231,9 +231,9 @@ module ActionController
231
231
  class LowerCamelArrayWoRootSerializerTest < ActionController::TestCase
232
232
  class WebLogController < ActionController::Base
233
233
  def render_array_without_root
234
- render json: [WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
235
- WebLog.new({name: 'Name 2', display_name: 'Display Name 2'})],
236
- root: false,
234
+ render json: [WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
235
+ WebLog.new({name: 'Name 2', display_name: 'Display Name 2'})],
236
+ root: false,
237
237
  each_serializer: WebLogLowerCamelSerializer
238
238
  end
239
239
  end
@@ -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,15 +49,31 @@ 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
58
58
  end
59
59
  end
60
60
 
61
+ def test_serialization_embedding_ids_in_common_root_key
62
+ post_serializer = AREmbeddedSerializer.new(@post)
63
+
64
+ embed(AREmbeddedSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do
65
+ embed(ARCommentSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do
66
+ assert_equal({
67
+ 'ar_tags' => [{ name: 'short' },
68
+ { name: 'whiny' },
69
+ { name: 'happy' }],
70
+ 'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
71
+ { body: 'i liked it', 'ar_tag_ids' => [3, 1] }]
72
+ }, post_serializer.as_json[:linked])
73
+ end
74
+ end
75
+ end
76
+
61
77
  private
62
78
 
63
79
  def embed(serializer_class, options = {})
@@ -66,6 +82,7 @@ module ActiveModel
66
82
  serializer_class._associations.each_value do |association|
67
83
  association.embed = options[:embed]
68
84
  association.embed_in_root = options[:embed_in_root]
85
+ association.embed_in_root_key = options[:embed_in_root_key]
69
86
  end
70
87
 
71
88
  yield
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)
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,2 @@
1
+ class AccountsController < ApplicationController
2
+ end
@@ -0,0 +1,2 @@
1
+ module AccountsHelper
2
+ end
@@ -0,0 +1,3 @@
1
+ class AccountSerializer < ActiveModel::Serializer
2
+ attributes :id
3
+ end
@@ -0,0 +1 @@
1
+ Rails.application.routes.draw { }
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class ArraySerializer
5
+ class OptionsTest < Minitest::Test
6
+ def test_custom_options_are_accessible_from_serializer
7
+
8
+ array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
9
+ Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
10
+ serializer = ArraySerializer.new(array, only: [:name], context: {foo: :bar})
11
+
12
+ assert_equal({foo: :bar}, serializer.context)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -35,6 +35,23 @@ module ActiveModel
35
35
  end
36
36
  end
37
37
 
38
+ class CustomSerializerClassTest < Minitest::Test
39
+ def setup
40
+ Object.const_set(:CustomSerializer, Class.new)
41
+ end
42
+
43
+ def teardown
44
+ Object.send(:remove_const, :CustomSerializer)
45
+ end
46
+
47
+ def test_serializer_for_array_returns_appropriate_type
48
+ object = {}
49
+ def object.serializer_class; CustomSerializer; end
50
+
51
+ assert_equal CustomSerializer, Serializer.serializer_for(object)
52
+ end
53
+ end
54
+
38
55
  class ModelSerializationTest < Minitest::Test
39
56
  def test_array_serializer_serializes_models
40
57
  array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
@@ -85,7 +102,7 @@ module ActiveModel
85
102
  {title: "Title 1", body: "Body 1", "comment_ids" => @post1.comments.map(&:object_id) },
86
103
  {title: "Title 2", body: "Body 2", "comment_ids" => @post2.comments.map(&:object_id) }
87
104
  ],
88
- comments: [
105
+ 'comments' => [
89
106
  {content: "C1"},
90
107
  {content: "C2"},
91
108
  {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
@@ -14,6 +14,36 @@ module ActiveModel
14
14
  assert_equal([:comments],
15
15
  another_inherited_serializer_klass._associations.keys)
16
16
  end
17
+ def test_multiple_nested_associations
18
+ parent = SelfReferencingUserParent.new(name: "The Parent")
19
+ child = SelfReferencingUser.new(name: "The child", parent: parent)
20
+ self_referencing_user_serializer = SelfReferencingUserSerializer.new(child)
21
+ result = self_referencing_user_serializer.as_json
22
+ expected_result = {
23
+ "self_referencing_user"=>{
24
+ :name=>"The child",
25
+ "type_id"=>child.type.object_id,
26
+ "parent_id"=>child.parent.object_id
27
+
28
+ },
29
+ "types"=>[
30
+ {
31
+ :name=>"N1",
32
+ },
33
+ {
34
+ :name=>"N2",
35
+ }
36
+ ],
37
+ "parents"=>[
38
+ {
39
+ :name=>"N1",
40
+ "type_id"=>child.parent.type.object_id,
41
+ "parent_id"=>nil
42
+ }
43
+ ]
44
+ }
45
+ assert_equal(expected_result, result)
46
+ end
17
47
  end
18
48
  end
19
49
  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