active_model_serializers 0.10.5 → 0.10.6
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/.rubocop.yml +4 -1
- data/CHANGELOG.md +16 -2
- data/README.md +2 -2
- data/Rakefile +1 -30
- data/active_model_serializers.gemspec +1 -1
- data/bin/rubocop +38 -0
- data/docs/general/adapters.md +25 -9
- data/docs/general/getting_started.md +1 -1
- data/docs/general/rendering.md +18 -4
- data/docs/general/serializers.md +21 -2
- data/docs/howto/add_pagination_links.md +1 -1
- data/docs/integrations/ember-and-json-api.md +3 -0
- data/lib/active_model/serializer.rb +252 -74
- data/lib/active_model/serializer/association.rb +51 -14
- data/lib/active_model/serializer/belongs_to_reflection.rb +5 -1
- data/lib/active_model/serializer/concerns/caching.rb +29 -21
- data/lib/active_model/serializer/has_many_reflection.rb +4 -1
- data/lib/active_model/serializer/has_one_reflection.rb +1 -1
- data/lib/active_model/serializer/lazy_association.rb +95 -0
- data/lib/active_model/serializer/reflection.rb +119 -75
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers/adapter/json_api.rb +30 -17
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +38 -9
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +9 -0
- data/lib/active_model_serializers/model.rb +5 -4
- data/lib/tasks/rubocop.rake +53 -0
- data/test/action_controller/adapter_selector_test.rb +2 -2
- data/test/serializers/associations_test.rb +64 -31
- data/test/serializers/reflection_test.rb +427 -0
- metadata +9 -12
- data/lib/active_model/serializer/collection_reflection.rb +0 -7
- data/lib/active_model/serializer/concerns/associations.rb +0 -102
- data/lib/active_model/serializer/concerns/attributes.rb +0 -82
- data/lib/active_model/serializer/concerns/configuration.rb +0 -59
- data/lib/active_model/serializer/concerns/links.rb +0 -35
- data/lib/active_model/serializer/concerns/meta.rb +0 -29
- data/lib/active_model/serializer/concerns/type.rb +0 -25
- data/lib/active_model/serializer/singular_reflection.rb +0 -7
|
@@ -257,7 +257,8 @@ module ActiveModelSerializers
|
|
|
257
257
|
|
|
258
258
|
def process_relationships(serializer, include_slice)
|
|
259
259
|
serializer.associations(include_slice).each do |association|
|
|
260
|
-
|
|
260
|
+
# TODO(BF): Process relationship without evaluating lazy_association
|
|
261
|
+
process_relationship(association.lazy_association.serializer, include_slice[association.key])
|
|
261
262
|
end
|
|
262
263
|
end
|
|
263
264
|
|
|
@@ -294,20 +295,8 @@ module ActiveModelSerializers
|
|
|
294
295
|
|
|
295
296
|
# {http://jsonapi.org/format/#document-resource-objects Document Resource Objects}
|
|
296
297
|
def resource_object_for(serializer, include_slice = {})
|
|
297
|
-
resource_object = serializer
|
|
298
|
-
resource_object = ResourceIdentifier.new(serializer, instance_options).as_json
|
|
299
|
-
|
|
300
|
-
requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
|
|
301
|
-
attributes = attributes_for(serializer, requested_fields)
|
|
302
|
-
resource_object[:attributes] = attributes if attributes.any?
|
|
303
|
-
resource_object
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
requested_associations = fieldset.fields_for(resource_object[:type]) || '*'
|
|
307
|
-
relationships = relationships_for(serializer, requested_associations, include_slice)
|
|
308
|
-
resource_object[:relationships] = relationships if relationships.any?
|
|
298
|
+
resource_object = data_for(serializer, include_slice)
|
|
309
299
|
|
|
310
|
-
links = links_for(serializer)
|
|
311
300
|
# toplevel_links
|
|
312
301
|
# definition:
|
|
313
302
|
# allOf
|
|
@@ -321,7 +310,10 @@ module ActiveModelSerializers
|
|
|
321
310
|
# prs:
|
|
322
311
|
# https://github.com/rails-api/active_model_serializers/pull/1247
|
|
323
312
|
# https://github.com/rails-api/active_model_serializers/pull/1018
|
|
324
|
-
|
|
313
|
+
if (links = links_for(serializer)).any?
|
|
314
|
+
resource_object ||= {}
|
|
315
|
+
resource_object[:links] = links
|
|
316
|
+
end
|
|
325
317
|
|
|
326
318
|
# toplevel_meta
|
|
327
319
|
# alias meta
|
|
@@ -331,12 +323,33 @@ module ActiveModelSerializers
|
|
|
331
323
|
# {
|
|
332
324
|
# :'git-ref' => 'abc123'
|
|
333
325
|
# }
|
|
334
|
-
meta = meta_for(serializer)
|
|
335
|
-
|
|
326
|
+
if (meta = meta_for(serializer)).present?
|
|
327
|
+
resource_object ||= {}
|
|
328
|
+
resource_object[:meta] = meta
|
|
329
|
+
end
|
|
336
330
|
|
|
337
331
|
resource_object
|
|
338
332
|
end
|
|
339
333
|
|
|
334
|
+
def data_for(serializer, include_slice)
|
|
335
|
+
data = serializer.fetch(self) do
|
|
336
|
+
resource_object = ResourceIdentifier.new(serializer, instance_options).as_json
|
|
337
|
+
break nil if resource_object.nil?
|
|
338
|
+
|
|
339
|
+
requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
|
|
340
|
+
attributes = attributes_for(serializer, requested_fields)
|
|
341
|
+
resource_object[:attributes] = attributes if attributes.any?
|
|
342
|
+
resource_object
|
|
343
|
+
end
|
|
344
|
+
data.tap do |resource_object|
|
|
345
|
+
next if resource_object.nil?
|
|
346
|
+
# NOTE(BF): the attributes are cached above, separately from the relationships, below.
|
|
347
|
+
requested_associations = fieldset.fields_for(resource_object[:type]) || '*'
|
|
348
|
+
relationships = relationships_for(serializer, requested_associations, include_slice)
|
|
349
|
+
resource_object[:relationships] = relationships if relationships.any?
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
340
353
|
# {http://jsonapi.org/format/#document-resource-object-relationships Document Resource Object Relationship}
|
|
341
354
|
# relationships
|
|
342
355
|
# definition:
|
|
@@ -15,9 +15,7 @@ module ActiveModelSerializers
|
|
|
15
15
|
def as_json
|
|
16
16
|
hash = {}
|
|
17
17
|
|
|
18
|
-
if association.
|
|
19
|
-
hash[:data] = data_for(association)
|
|
20
|
-
end
|
|
18
|
+
hash[:data] = data_for(association) if association.include_data?
|
|
21
19
|
|
|
22
20
|
links = links_for(association)
|
|
23
21
|
hash[:links] = links if links.any?
|
|
@@ -35,14 +33,45 @@ module ActiveModelSerializers
|
|
|
35
33
|
|
|
36
34
|
private
|
|
37
35
|
|
|
36
|
+
# TODO(BF): Avoid db hit on belong_to_ releationship by using foreign_key on self
|
|
38
37
|
def data_for(association)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
if association.collection?
|
|
39
|
+
data_for_many(association)
|
|
40
|
+
else
|
|
41
|
+
data_for_one(association)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def data_for_one(association)
|
|
46
|
+
if association.belongs_to? &&
|
|
47
|
+
parent_serializer.object.respond_to?(association.reflection.foreign_key)
|
|
48
|
+
id = parent_serializer.object.send(association.reflection.foreign_key)
|
|
49
|
+
type = association.reflection.type.to_s
|
|
50
|
+
ResourceIdentifier.for_type_with_id(type, id, serializable_resource_options)
|
|
51
|
+
else
|
|
52
|
+
# TODO(BF): Process relationship without evaluating lazy_association
|
|
53
|
+
serializer = association.lazy_association.serializer
|
|
54
|
+
if (virtual_value = association.virtual_value)
|
|
55
|
+
virtual_value
|
|
56
|
+
elsif serializer && association.object
|
|
57
|
+
ResourceIdentifier.new(serializer, serializable_resource_options).as_json
|
|
58
|
+
else
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def data_for_many(association)
|
|
65
|
+
# TODO(BF): Process relationship without evaluating lazy_association
|
|
66
|
+
collection_serializer = association.lazy_association.serializer
|
|
67
|
+
if collection_serializer.respond_to?(:each)
|
|
68
|
+
collection_serializer.map do |serializer|
|
|
69
|
+
ResourceIdentifier.new(serializer, serializable_resource_options).as_json
|
|
70
|
+
end
|
|
71
|
+
elsif (virtual_value = association.virtual_value)
|
|
43
72
|
virtual_value
|
|
44
|
-
|
|
45
|
-
|
|
73
|
+
else
|
|
74
|
+
[]
|
|
46
75
|
end
|
|
47
76
|
end
|
|
48
77
|
|
|
@@ -22,6 +22,14 @@ module ActiveModelSerializers
|
|
|
22
22
|
JsonApi.send(:transform_key_casing!, raw_type, transform_options)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def self.for_type_with_id(type, id, options)
|
|
26
|
+
return nil if id.blank?
|
|
27
|
+
{
|
|
28
|
+
id: id.to_s,
|
|
29
|
+
type: type_for(:no_class_needed, type, options)
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
25
33
|
# {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects}
|
|
26
34
|
def initialize(serializer, options)
|
|
27
35
|
@id = id_for(serializer)
|
|
@@ -29,6 +37,7 @@ module ActiveModelSerializers
|
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
def as_json
|
|
40
|
+
return nil if id.blank?
|
|
32
41
|
{ id: id, type: type }
|
|
33
42
|
end
|
|
34
43
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# ActiveModelSerializers::Model is a convenient superclass for making your models
|
|
2
2
|
# from Plain-Old Ruby Objects (PORO). It also serves as a reference implementation
|
|
3
3
|
# that satisfies ActiveModel::Serializer::Lint::Tests.
|
|
4
|
+
require 'active_support/core_ext/hash'
|
|
4
5
|
module ActiveModelSerializers
|
|
5
6
|
class Model
|
|
6
7
|
include ActiveModel::Serializers::JSON
|
|
7
8
|
include ActiveModel::Model
|
|
8
9
|
|
|
9
|
-
# Declare names of attributes to be included in +
|
|
10
|
+
# Declare names of attributes to be included in +attributes+ hash.
|
|
10
11
|
# Is only available as a class-method since the ActiveModel::Serialization mixin in Rails
|
|
11
12
|
# uses an +attribute_names+ local variable, which may conflict if we were to add instance methods here.
|
|
12
13
|
#
|
|
@@ -19,8 +20,8 @@ module ActiveModelSerializers
|
|
|
19
20
|
|
|
20
21
|
# Easily declare instance attributes with setters and getters for each.
|
|
21
22
|
#
|
|
22
|
-
#
|
|
23
|
-
# However, the hash
|
|
23
|
+
# To initialize an instance, all attributes must have setters.
|
|
24
|
+
# However, the hash returned by +attributes+ instance method will ALWAYS
|
|
24
25
|
# be the value of the initial attributes, regardless of what accessors are defined.
|
|
25
26
|
# The only way to change the change the attributes after initialization is
|
|
26
27
|
# to mutate the +attributes+ directly.
|
|
@@ -58,7 +59,7 @@ module ActiveModelSerializers
|
|
|
58
59
|
|
|
59
60
|
# Override the +attributes+ method so that the hash is derived from +attribute_names+.
|
|
60
61
|
#
|
|
61
|
-
# The
|
|
62
|
+
# The fields in +attribute_names+ determines the returned hash.
|
|
62
63
|
# +attributes+ are returned frozen to prevent any expectations that mutation affects
|
|
63
64
|
# the actual values in the model.
|
|
64
65
|
def attributes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'rubocop'
|
|
3
|
+
require 'rubocop/rake_task'
|
|
4
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
5
|
+
else
|
|
6
|
+
require 'rbconfig'
|
|
7
|
+
# https://github.com/bundler/bundler/blob/1b3eb2465a/lib/bundler/constants.rb#L2
|
|
8
|
+
windows_platforms = /(msdos|mswin|djgpp|mingw)/
|
|
9
|
+
if RbConfig::CONFIG['host_os'] =~ windows_platforms
|
|
10
|
+
desc 'No-op rubocop on Windows-- unsupported platform'
|
|
11
|
+
task :rubocop do
|
|
12
|
+
puts 'Skipping rubocop on Windows'
|
|
13
|
+
end
|
|
14
|
+
elsif defined?(::Rubinius)
|
|
15
|
+
desc 'No-op rubocop to avoid rbx segfault'
|
|
16
|
+
task :rubocop do
|
|
17
|
+
puts 'Skipping rubocop on rbx due to segfault'
|
|
18
|
+
puts 'https://github.com/rubinius/rubinius/issues/3499'
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
Rake::Task[:rubocop].clear if Rake::Task.task_defined?(:rubocop)
|
|
22
|
+
patterns = [
|
|
23
|
+
'Gemfile',
|
|
24
|
+
'Rakefile',
|
|
25
|
+
'lib/**/*.{rb,rake}',
|
|
26
|
+
'config/**/*.rb',
|
|
27
|
+
'app/**/*.rb',
|
|
28
|
+
'test/**/*.rb'
|
|
29
|
+
]
|
|
30
|
+
desc 'Execute rubocop'
|
|
31
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
|
32
|
+
task.options = ['--rails', '--display-cop-names', '--display-style-guide']
|
|
33
|
+
task.formatters = ['progress']
|
|
34
|
+
task.patterns = patterns
|
|
35
|
+
task.fail_on_error = true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
namespace :rubocop do
|
|
39
|
+
desc 'Auto-gen rubocop config'
|
|
40
|
+
task :auto_gen_config do
|
|
41
|
+
options = ['--auto-gen-config'].concat patterns
|
|
42
|
+
require 'benchmark'
|
|
43
|
+
result = 0
|
|
44
|
+
cli = RuboCop::CLI.new
|
|
45
|
+
time = Benchmark.realtime do
|
|
46
|
+
result = cli.run(options)
|
|
47
|
+
end
|
|
48
|
+
puts "Finished in #{time} seconds" if cli.options[:debug]
|
|
49
|
+
abort('RuboCop failed!') if result.nonzero?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -19,7 +19,7 @@ module ActionController
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def render_using_adapter_override
|
|
22
|
-
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
22
|
+
@profile = Profile.new(id: 'render_using_adapter_override', name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
23
23
|
render json: @profile, adapter: :json_api
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -41,7 +41,7 @@ module ActionController
|
|
|
41
41
|
|
|
42
42
|
expected = {
|
|
43
43
|
data: {
|
|
44
|
-
id:
|
|
44
|
+
id: 'render_using_adapter_override',
|
|
45
45
|
type: 'profiles',
|
|
46
46
|
attributes: {
|
|
47
47
|
name: 'Name 1',
|
|
@@ -30,18 +30,17 @@ module ActiveModel
|
|
|
30
30
|
def test_has_many_and_has_one
|
|
31
31
|
@author_serializer.associations.each do |association|
|
|
32
32
|
key = association.key
|
|
33
|
-
serializer = association.serializer
|
|
34
|
-
options = association.options
|
|
33
|
+
serializer = association.lazy_association.serializer
|
|
35
34
|
|
|
36
35
|
case key
|
|
37
36
|
when :posts
|
|
38
|
-
assert_equal true,
|
|
37
|
+
assert_equal true, association.include_data?
|
|
39
38
|
assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
|
|
40
39
|
when :bio
|
|
41
|
-
assert_equal true,
|
|
40
|
+
assert_equal true, association.include_data?
|
|
42
41
|
assert_nil serializer
|
|
43
42
|
when :roles
|
|
44
|
-
assert_equal true,
|
|
43
|
+
assert_equal true, association.include_data?
|
|
45
44
|
assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
|
|
46
45
|
else
|
|
47
46
|
flunk "Unknown association: #{key}"
|
|
@@ -56,12 +55,11 @@ module ActiveModel
|
|
|
56
55
|
end
|
|
57
56
|
post_serializer_class.new(@post).associations.each do |association|
|
|
58
57
|
key = association.key
|
|
59
|
-
serializer = association.serializer
|
|
60
|
-
options = association.options
|
|
58
|
+
serializer = association.lazy_association.serializer
|
|
61
59
|
|
|
62
60
|
assert_equal :tags, key
|
|
63
61
|
assert_nil serializer
|
|
64
|
-
assert_equal [{ id: 'tagid', name: '#hashtagged' }].to_json,
|
|
62
|
+
assert_equal [{ id: 'tagid', name: '#hashtagged' }].to_json, association.virtual_value.to_json
|
|
65
63
|
end
|
|
66
64
|
end
|
|
67
65
|
|
|
@@ -70,7 +68,7 @@ module ActiveModel
|
|
|
70
68
|
.associations
|
|
71
69
|
.detect { |assoc| assoc.key == :comments }
|
|
72
70
|
|
|
73
|
-
comment_serializer = association.serializer.first
|
|
71
|
+
comment_serializer = association.lazy_association.serializer.first
|
|
74
72
|
class << comment_serializer
|
|
75
73
|
def custom_options
|
|
76
74
|
instance_options
|
|
@@ -82,7 +80,7 @@ module ActiveModel
|
|
|
82
80
|
def test_belongs_to
|
|
83
81
|
@comment_serializer.associations.each do |association|
|
|
84
82
|
key = association.key
|
|
85
|
-
serializer = association.serializer
|
|
83
|
+
serializer = association.lazy_association.serializer
|
|
86
84
|
|
|
87
85
|
case key
|
|
88
86
|
when :post
|
|
@@ -93,7 +91,7 @@ module ActiveModel
|
|
|
93
91
|
flunk "Unknown association: #{key}"
|
|
94
92
|
end
|
|
95
93
|
|
|
96
|
-
assert_equal true, association.
|
|
94
|
+
assert_equal true, association.include_data?
|
|
97
95
|
end
|
|
98
96
|
end
|
|
99
97
|
|
|
@@ -139,6 +137,34 @@ module ActiveModel
|
|
|
139
137
|
assert expected_association_keys.include? :site
|
|
140
138
|
end
|
|
141
139
|
|
|
140
|
+
class BelongsToBlogModel < ::Model
|
|
141
|
+
attributes :id, :title
|
|
142
|
+
associations :blog
|
|
143
|
+
end
|
|
144
|
+
class BelongsToBlogModelSerializer < ActiveModel::Serializer
|
|
145
|
+
type :posts
|
|
146
|
+
belongs_to :blog
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_belongs_to_doesnt_load_record
|
|
150
|
+
attributes = { id: 1, title: 'Belongs to Blog', blog: Blog.new(id: 5) }
|
|
151
|
+
post = BelongsToBlogModel.new(attributes)
|
|
152
|
+
class << post
|
|
153
|
+
def blog
|
|
154
|
+
fail 'should use blog_id'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def blog_id
|
|
158
|
+
5
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
actual = serializable(post, adapter: :json_api, serializer: BelongsToBlogModelSerializer).as_json
|
|
163
|
+
expected = { data: { id: '1', type: 'posts', relationships: { blog: { data: { id: '5', type: 'blogs' } } } } }
|
|
164
|
+
|
|
165
|
+
assert_equal expected, actual
|
|
166
|
+
end
|
|
167
|
+
|
|
142
168
|
class InlineAssociationTestPostSerializer < ActiveModel::Serializer
|
|
143
169
|
has_many :comments
|
|
144
170
|
has_many :comments, key: :last_comments do
|
|
@@ -203,11 +229,11 @@ module ActiveModel
|
|
|
203
229
|
@post_serializer.associations.each do |association|
|
|
204
230
|
case association.key
|
|
205
231
|
when :comments
|
|
206
|
-
assert_instance_of(ResourceNamespace::CommentSerializer, association.serializer.first)
|
|
232
|
+
assert_instance_of(ResourceNamespace::CommentSerializer, association.lazy_association.serializer.first)
|
|
207
233
|
when :author
|
|
208
|
-
assert_instance_of(ResourceNamespace::AuthorSerializer, association.serializer)
|
|
234
|
+
assert_instance_of(ResourceNamespace::AuthorSerializer, association.lazy_association.serializer)
|
|
209
235
|
when :description
|
|
210
|
-
assert_instance_of(ResourceNamespace::DescriptionSerializer, association.serializer)
|
|
236
|
+
assert_instance_of(ResourceNamespace::DescriptionSerializer, association.lazy_association.serializer)
|
|
211
237
|
else
|
|
212
238
|
flunk "Unknown association: #{key}"
|
|
213
239
|
end
|
|
@@ -245,11 +271,11 @@ module ActiveModel
|
|
|
245
271
|
@post_serializer.associations.each do |association|
|
|
246
272
|
case association.key
|
|
247
273
|
when :comments
|
|
248
|
-
assert_instance_of(PostSerializer::CommentSerializer, association.serializer.first)
|
|
274
|
+
assert_instance_of(PostSerializer::CommentSerializer, association.lazy_association.serializer.first)
|
|
249
275
|
when :author
|
|
250
|
-
assert_instance_of(PostSerializer::AuthorSerializer, association.serializer)
|
|
276
|
+
assert_instance_of(PostSerializer::AuthorSerializer, association.lazy_association.serializer)
|
|
251
277
|
when :description
|
|
252
|
-
assert_instance_of(PostSerializer::DescriptionSerializer, association.serializer)
|
|
278
|
+
assert_instance_of(PostSerializer::DescriptionSerializer, association.lazy_association.serializer)
|
|
253
279
|
else
|
|
254
280
|
flunk "Unknown association: #{key}"
|
|
255
281
|
end
|
|
@@ -260,7 +286,7 @@ module ActiveModel
|
|
|
260
286
|
def test_conditional_associations
|
|
261
287
|
model = Class.new(::Model) do
|
|
262
288
|
attributes :true, :false
|
|
263
|
-
associations :
|
|
289
|
+
associations :something
|
|
264
290
|
end.new(true: true, false: false)
|
|
265
291
|
|
|
266
292
|
scenarios = [
|
|
@@ -284,7 +310,7 @@ module ActiveModel
|
|
|
284
310
|
|
|
285
311
|
scenarios.each do |s|
|
|
286
312
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
287
|
-
belongs_to :
|
|
313
|
+
belongs_to :something, s[:options]
|
|
288
314
|
|
|
289
315
|
def true
|
|
290
316
|
true
|
|
@@ -296,7 +322,7 @@ module ActiveModel
|
|
|
296
322
|
end
|
|
297
323
|
|
|
298
324
|
hash = serializable(model, serializer: serializer).serializable_hash
|
|
299
|
-
assert_equal(s[:included], hash.key?(:
|
|
325
|
+
assert_equal(s[:included], hash.key?(:something), "Error with #{s[:options]}")
|
|
300
326
|
end
|
|
301
327
|
end
|
|
302
328
|
|
|
@@ -341,8 +367,8 @@ module ActiveModel
|
|
|
341
367
|
@author_serializer = AuthorSerializer.new(@author)
|
|
342
368
|
@inherited_post_serializer = InheritedPostSerializer.new(@post)
|
|
343
369
|
@inherited_author_serializer = InheritedAuthorSerializer.new(@author)
|
|
344
|
-
@author_associations = @author_serializer.associations.to_a
|
|
345
|
-
@inherited_author_associations = @inherited_author_serializer.associations.to_a
|
|
370
|
+
@author_associations = @author_serializer.associations.to_a.sort_by(&:name)
|
|
371
|
+
@inherited_author_associations = @inherited_author_serializer.associations.to_a.sort_by(&:name)
|
|
346
372
|
@post_associations = @post_serializer.associations.to_a
|
|
347
373
|
@inherited_post_associations = @inherited_post_serializer.associations.to_a
|
|
348
374
|
end
|
|
@@ -361,28 +387,35 @@ module ActiveModel
|
|
|
361
387
|
|
|
362
388
|
test 'a serializer inheriting from another serializer can redefine has_many and has_one associations' do
|
|
363
389
|
expected = [:roles, :bio].sort
|
|
364
|
-
result = (@inherited_author_associations - @author_associations).map(&:name)
|
|
390
|
+
result = (@inherited_author_associations.map(&:reflection) - @author_associations.map(&:reflection)).map(&:name)
|
|
365
391
|
assert_equal(result, expected)
|
|
392
|
+
assert_equal [true, false, true], @inherited_author_associations.map(&:polymorphic?)
|
|
393
|
+
assert_equal [false, false, false], @author_associations.map(&:polymorphic?)
|
|
366
394
|
end
|
|
367
395
|
|
|
368
396
|
test 'a serializer inheriting from another serializer can redefine belongs_to associations' do
|
|
369
397
|
assert_equal [:author, :comments, :blog], @post_associations.map(&:name)
|
|
370
398
|
assert_equal [:author, :comments, :blog, :comments], @inherited_post_associations.map(&:name)
|
|
371
399
|
|
|
372
|
-
refute @post_associations.detect { |assoc| assoc.name == :author }.
|
|
373
|
-
|
|
400
|
+
refute @post_associations.detect { |assoc| assoc.name == :author }.polymorphic?
|
|
401
|
+
assert @inherited_post_associations.detect { |assoc| assoc.name == :author }.polymorphic?
|
|
374
402
|
|
|
375
|
-
refute @post_associations.detect { |assoc| assoc.name == :comments }.
|
|
403
|
+
refute @post_associations.detect { |assoc| assoc.name == :comments }.key?
|
|
376
404
|
original_comment_assoc, new_comments_assoc = @inherited_post_associations.select { |assoc| assoc.name == :comments }
|
|
377
|
-
refute original_comment_assoc.
|
|
378
|
-
assert_equal :reviews, new_comments_assoc.
|
|
379
|
-
|
|
380
|
-
|
|
405
|
+
refute original_comment_assoc.key?
|
|
406
|
+
assert_equal :reviews, new_comments_assoc.key
|
|
407
|
+
|
|
408
|
+
original_blog = @post_associations.detect { |assoc| assoc.name == :blog }
|
|
409
|
+
inherited_blog = @inherited_post_associations.detect { |assoc| assoc.name == :blog }
|
|
410
|
+
original_parent_serializer = original_blog.lazy_association.association_options.delete(:parent_serializer)
|
|
411
|
+
inherited_parent_serializer = inherited_blog.lazy_association.association_options.delete(:parent_serializer)
|
|
412
|
+
assert_equal PostSerializer, original_parent_serializer.class
|
|
413
|
+
assert_equal InheritedPostSerializer, inherited_parent_serializer.class
|
|
381
414
|
end
|
|
382
415
|
|
|
383
416
|
test 'a serializer inheriting from another serializer can have an additional association with the same name but with different key' do
|
|
384
417
|
expected = [:author, :comments, :blog, :reviews].sort
|
|
385
|
-
result = @inherited_post_serializer.associations.map
|
|
418
|
+
result = @inherited_post_serializer.associations.map(&:key).sort
|
|
386
419
|
assert_equal(result, expected)
|
|
387
420
|
end
|
|
388
421
|
end
|