active_model_serializers 0.9.1 → 0.9.2

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -6
  3. data/README.md +17 -109
  4. data/lib/action_controller/serialization.rb +8 -27
  5. data/lib/action_controller/serialization_test_case.rb +4 -4
  6. data/lib/active_model/array_serializer.rb +5 -12
  7. data/lib/active_model/serializable.rb +2 -24
  8. data/lib/active_model/serializer.rb +36 -70
  9. data/lib/active_model/serializer/{association.rb → associations.rb} +52 -8
  10. data/lib/active_model/serializer/railtie.rb +0 -8
  11. data/lib/active_model/serializer/version.rb +1 -1
  12. data/lib/active_model_serializers.rb +1 -1
  13. data/test/fixtures/poro.rb +1 -110
  14. data/test/integration/action_controller/serialization_test.rb +0 -16
  15. data/test/integration/action_controller/serialization_test_case_test.rb +0 -10
  16. data/test/integration/active_record/active_record_test.rb +2 -2
  17. data/test/test_app.rb +0 -3
  18. data/test/unit/active_model/array_serializer/serialization_test.rb +1 -1
  19. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +0 -15
  20. data/test/unit/active_model/serializer/attributes_test.rb +0 -16
  21. data/test/unit/active_model/serializer/config_test.rb +0 -3
  22. data/test/unit/active_model/serializer/has_many_test.rb +16 -51
  23. data/test/unit/active_model/serializer/has_one_test.rb +0 -32
  24. data/test/unit/active_model/serializer/options_test.rb +0 -19
  25. metadata +3 -18
  26. data/lib/active_model/serializable/utils.rb +0 -16
  27. data/lib/active_model/serializer/association/has_many.rb +0 -39
  28. data/lib/active_model/serializer/association/has_one.rb +0 -25
  29. data/test/fixtures/template.html.erb +0 -1
  30. data/test/integration/action_controller/namespaced_serialization_test.rb +0 -96
  31. data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +0 -189
  32. data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +0 -27
  33. data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +0 -196
  34. data/test/unit/active_model/serializer/url_helpers_test.rb +0 -35
@@ -1,6 +1,4 @@
1
1
  require 'active_model/default_serializer'
2
- require 'active_model/serializer/association/has_one'
3
- require 'active_model/serializer/association/has_many'
4
2
 
5
3
  module ActiveModel
6
4
  class Serializer
@@ -15,7 +13,6 @@ module ActiveModel
15
13
  @name = name.to_s
16
14
  @options = options
17
15
  self.embed = options.fetch(:embed) { CONFIG.embed }
18
- @polymorphic = options.fetch(:polymorphic, false)
19
16
  @embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } }
20
17
  @key_format = options.fetch(:key_format) { CONFIG.key_format }
21
18
  @embed_key = options[:embed_key] || :id
@@ -28,22 +25,21 @@ module ActiveModel
28
25
  @serializer_from_options = serializer.is_a?(String) ? serializer.constantize : serializer
29
26
  end
30
27
 
31
- attr_reader :name, :embed_ids, :embed_objects, :polymorphic
28
+ attr_reader :name, :embed_ids, :embed_objects
32
29
  attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :root_key, :serializer_from_options, :options, :key_format, :embed_in_root_key, :embed_namespace
33
30
  alias embed_ids? embed_ids
34
31
  alias embed_objects? embed_objects
35
32
  alias embed_in_root? embed_in_root
36
33
  alias embed_in_root_key? embed_in_root_key
37
34
  alias embed_namespace? embed_namespace
38
- alias polymorphic? polymorphic
39
35
 
40
36
  def embed=(embed)
41
37
  @embed_ids = embed == :id || embed == :ids
42
38
  @embed_objects = embed == :object || embed == :objects
43
39
  end
44
40
 
45
- def serializer_from_object(object, options = {})
46
- Serializer.serializer_for(object, options)
41
+ def serializer_from_object(object)
42
+ Serializer.serializer_for(object)
47
43
  end
48
44
 
49
45
  def default_serializer
@@ -51,7 +47,55 @@ module ActiveModel
51
47
  end
52
48
 
53
49
  def build_serializer(object, options = {})
54
- serializer_class(object, options).new(object, options.merge(self.options))
50
+ serializer_class(object).new(object, options.merge(self.options))
51
+ end
52
+
53
+ class HasOne < Association
54
+ def initialize(name, *args)
55
+ super
56
+ @root_key = @embedded_key.to_s.pluralize
57
+ @key ||= "#{name}_id"
58
+ end
59
+
60
+ def serializer_class(object)
61
+ serializer_from_options || serializer_from_object(object) || default_serializer
62
+ end
63
+
64
+ def build_serializer(object, options = {})
65
+ options[:_wrap_in_array] = embed_in_root?
66
+ super
67
+ end
68
+ end
69
+
70
+ class HasMany < Association
71
+ def initialize(name, *args)
72
+ super
73
+ @root_key = @embedded_key
74
+ @key ||= "#{name.to_s.singularize}_ids"
75
+ end
76
+
77
+ def serializer_class(object)
78
+ if use_array_serializer?
79
+ ArraySerializer
80
+ else
81
+ serializer_from_options
82
+ end
83
+ end
84
+
85
+ def options
86
+ if use_array_serializer?
87
+ { each_serializer: serializer_from_options }.merge! super
88
+ else
89
+ super
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def use_array_serializer?
96
+ !serializer_from_options ||
97
+ serializer_from_options && !(serializer_from_options <= ArraySerializer)
98
+ end
55
99
  end
56
100
  end
57
101
  end
@@ -6,13 +6,5 @@ module ActiveModel
6
6
  require 'active_model/serializer/generators/serializer/scaffold_controller_generator'
7
7
  require 'active_model/serializer/generators/resource_override'
8
8
  end
9
-
10
- initializer 'include_routes.active_model_serializer' do |app|
11
- ActiveSupport.on_load(:active_model_serializers) do
12
- include app.routes.url_helpers
13
- end
14
- end
15
9
  end
16
10
  end
17
-
18
- ActiveSupport.run_load_hooks(:active_model_serializers, ActiveModel::Serializer)
@@ -1,5 +1,5 @@
1
1
  module ActiveModel
2
2
  class Serializer
3
- VERSION = '0.9.1'
3
+ VERSION = '0.9.2'
4
4
  end
5
5
  end
@@ -9,7 +9,7 @@ begin
9
9
  require 'action_controller/serialization'
10
10
  require 'action_controller/serialization_test_case'
11
11
 
12
- ActiveSupport.on_load(:action_controller) do
12
+ ActiveSupport.on_load(:after_initialize) do
13
13
  if ::ActionController::Serialization.enabled
14
14
  ActionController::Base.send(:include, ::ActionController::Serialization)
15
15
  ActionController::TestCase.send(:include, ::ActionController::SerializationAssertions)
@@ -1,13 +1,11 @@
1
1
  class Model
2
- def initialize(hash = {})
2
+ def initialize(hash={})
3
3
  @attributes = hash
4
4
  end
5
5
 
6
6
  def read_attribute_for_serialization(name)
7
7
  if name == :id || name == 'id'
8
8
  object_id
9
- elsif respond_to?(name)
10
- send name
11
9
  else
12
10
  @attributes[name]
13
11
  end
@@ -24,22 +22,9 @@ class User < Model
24
22
  end
25
23
  end
26
24
 
27
- class UserInfo < Model
28
- def user
29
- @user ||= User.new(name: 'N1', email: 'E1')
30
- end
31
- end
32
-
33
25
  class Profile < Model
34
26
  end
35
27
 
36
- class Category < Model
37
- def posts
38
- @posts ||= [Post.new(title: 'T1', body: 'B1'),
39
- Post.new(title: 'T2', body: 'B2')]
40
- end
41
- end
42
-
43
28
  class Post < Model
44
29
  def comments
45
30
  @comments ||= [Comment.new(content: 'C1'),
@@ -47,37 +32,12 @@ class Post < Model
47
32
  end
48
33
  end
49
34
 
50
- class SpecialPost < Post
51
- def special_comment
52
- @speical_comment ||= Comment.new(content: 'special')
53
- end
54
- end
55
-
56
35
  class Comment < Model
57
36
  end
58
37
 
59
38
  class WebLog < Model
60
39
  end
61
40
 
62
- class Interview < Model
63
- def attachment
64
- @attachment ||= Image.new(url: 'U1')
65
- end
66
- end
67
-
68
- class Mail < Model
69
- def attachments
70
- @attachments ||= [Image.new(url: 'U1'),
71
- Video.new(html: 'H1')]
72
- end
73
- end
74
-
75
- class Image < Model
76
- end
77
-
78
- class Video < Model
79
- end
80
-
81
41
  ###
82
42
  ## Serializers
83
43
  ###
@@ -87,10 +47,6 @@ class UserSerializer < ActiveModel::Serializer
87
47
  has_one :profile
88
48
  end
89
49
 
90
- class UserInfoSerializer < ActiveModel::Serializer
91
- has_one :user
92
- end
93
-
94
50
  class ProfileSerializer < ActiveModel::Serializer
95
51
  def description
96
52
  description = object.read_attribute_for_serialization(:description)
@@ -100,28 +56,12 @@ class ProfileSerializer < ActiveModel::Serializer
100
56
  attributes :name, :description
101
57
  end
102
58
 
103
- class DifferentProfileSerializer < ActiveModel::Serializer
104
- attributes :name
105
- end
106
-
107
- class CategorySerializer < ActiveModel::Serializer
108
- attributes :name
109
-
110
- has_many :posts
111
- end
112
-
113
59
  class PostSerializer < ActiveModel::Serializer
114
60
  attributes :title, :body
115
61
 
116
62
  has_many :comments
117
63
  end
118
64
 
119
- class SpecialPostSerializer < ActiveModel::Serializer
120
- attributes :title, :body
121
- has_many :comments, root: :comments, embed_in_root: true, embed: :ids
122
- has_one :special_comment, root: :comments, embed_in_root: true, embed: :ids
123
- end
124
-
125
65
  class CommentSerializer < ActiveModel::Serializer
126
66
  attributes :content
127
67
  end
@@ -133,52 +73,3 @@ end
133
73
  class WebLogLowerCamelSerializer < WebLogSerializer
134
74
  format_keys :lower_camel
135
75
  end
136
-
137
- class InterviewSerializer < ActiveModel::Serializer
138
- attributes :text
139
-
140
- has_one :attachment, polymorphic: true
141
- end
142
-
143
- class MailSerializer < ActiveModel::Serializer
144
- attributes :body
145
-
146
- has_many :attachments, polymorphic: true
147
- end
148
-
149
- class ImageSerializer < ActiveModel::Serializer
150
- attributes :url
151
- end
152
-
153
- class VideoSerializer < ActiveModel::Serializer
154
- attributes :html
155
- end
156
-
157
- class ShortProfileSerializer < ::ProfileSerializer; end
158
-
159
- module TestNamespace
160
- class ProfileSerializer < ::ProfileSerializer; end
161
- class UserSerializer < ::UserSerializer; end
162
- end
163
-
164
- ActiveModel::Serializer.setup do |config|
165
- config.default_key_type = :name
166
- end
167
-
168
- class NameKeyUserSerializer < ActiveModel::Serializer
169
- attributes :name, :email
170
-
171
- has_one :profile
172
- end
173
-
174
- class NameKeyPostSerializer < ActiveModel::Serializer
175
- attributes :title, :body
176
-
177
- has_many :comments
178
- end
179
-
180
- ActiveModel::Serializer.setup do |config|
181
- config.default_key_type = nil
182
- end
183
-
184
-
@@ -283,21 +283,5 @@ module ActionController
283
283
  assert_equal("{\"my\":[{\"name\":\"Name 1\",\"email\":\"mail@server.com\",\"profile_id\":#{@controller.user.profile.object_id}}],\"profiles\":[{\"name\":\"N1\",\"description\":\"D1\"}]}", @response.body)
284
284
  end
285
285
  end
286
-
287
- class ExplicitEachSerializerWithEnumarableObjectTest < ActionController::TestCase
288
- class MyController < ActionController::Base
289
- def render_array
290
- render json: [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })].to_enum, each_serializer: DifferentProfileSerializer
291
- end
292
- end
293
-
294
- tests MyController
295
-
296
- def test_render_array
297
- get :render_array
298
- assert_equal 'application/json', @response.content_type
299
- assert_equal '{"my":[{"name":"Name 1"}]}', @response.body
300
- end
301
- end
302
286
  end
303
287
  end
@@ -11,11 +11,6 @@ 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
19
14
  end
20
15
 
21
16
  tests MyController
@@ -61,11 +56,6 @@ module ActionController
61
56
  end
62
57
  assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
63
58
  end
64
-
65
- def test_does_not_overwrite_notification_subscriptions
66
- get :render_template
67
- assert_template "template"
68
- end
69
59
  end
70
60
  end
71
61
  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
data/test/test_app.rb CHANGED
@@ -3,9 +3,6 @@ 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
9
6
 
10
7
  # Set up a logger to avoid creating a log directory on every run.
11
8
  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,7 +7,6 @@ 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
11
10
  end
12
11
 
13
12
  def test_build_serializer_for_array_called_twice
@@ -16,20 +15,6 @@ module ActiveModel
16
15
  assert_instance_of(PostSerializer, serializer)
17
16
  end
18
17
  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
33
18
  end
34
19
  end
35
20
  end
@@ -36,22 +36,6 @@ 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
55
39
  end
56
40
  end
57
41
  end
@@ -78,9 +78,6 @@ 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
84
81
  ensure
85
82
  PostSerializer._associations[:comments] = old_association
86
83
  CONFIG.clear
@@ -111,34 +111,17 @@ 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
-
135
118
  def test_associations_embedding_nothing_including_objects_serialization_using_as_json
136
119
  @association.embed = nil
137
120
  @association.embed_in_root = true
138
121
 
139
122
  assert_equal({
140
123
  'post' => { title: 'Title 1', body: 'Body 1' },
141
- 'comments' => [{ content: 'C1' }, { content: 'C2' }]
124
+ comments: [{ content: 'C1' }, { content: 'C2' }]
142
125
  }, @post_serializer.as_json)
143
126
  end
144
127
 
@@ -155,7 +138,7 @@ module ActiveModel
155
138
 
156
139
  assert_equal({
157
140
  'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
158
- 'comments' => [{ content: 'C1!' }, { content: 'C2!' }]
141
+ comments: [{ content: 'C1!' }, { content: 'C2!' }]
159
142
  }, @post_serializer.as_json)
160
143
  end
161
144
 
@@ -170,7 +153,7 @@ module ActiveModel
170
153
 
171
154
  assert_equal({
172
155
  'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
173
- 'comments' => { my_content: ['fake'] }
156
+ comments: { my_content: ['fake'] }
174
157
  }, @post_serializer.as_json)
175
158
  end
176
159
 
@@ -191,16 +174,16 @@ module ActiveModel
191
174
  @association.embed_in_root_key = :linked
192
175
  @association.embed = :ids
193
176
  assert_equal({
194
- 'post' => {
195
- title: 'Title 1', body: 'Body 1',
196
- 'comment_ids' => @post.comments.map(&:object_id)
197
- },
198
177
  linked: {
199
- 'comments' => [
178
+ comments: [
200
179
  { content: 'C1' },
201
180
  { content: 'C2' }
202
181
  ]
203
182
  },
183
+ 'post' => {
184
+ title: 'Title 1', body: 'Body 1',
185
+ 'comment_ids' => @post.comments.map(&:object_id)
186
+ }
204
187
  }, @post_serializer.as_json)
205
188
  end
206
189
 
@@ -211,18 +194,18 @@ module ActiveModel
211
194
  @association.embed_namespace = :links
212
195
  @association.key = :comments
213
196
  assert_equal({
214
- 'post' => {
215
- title: 'Title 1', body: 'Body 1',
216
- links: {
217
- comments: @post.comments.map(&:object_id)
218
- }
219
- },
220
197
  linked: {
221
- 'comments' => [
198
+ comments: [
222
199
  { content: 'C1' },
223
200
  { content: 'C2' }
224
201
  ]
225
202
  },
203
+ 'post' => {
204
+ title: 'Title 1', body: 'Body 1',
205
+ links: {
206
+ comments: @post.comments.map(&:object_id)
207
+ }
208
+ }
226
209
  }, @post_serializer.as_json)
227
210
  end
228
211
 
@@ -242,24 +225,6 @@ module ActiveModel
242
225
  }
243
226
  }, @post_serializer.as_json)
244
227
  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
263
228
  end
264
229
  end
265
230
  end