active_model_serializers 0.10.7 → 0.10.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +16 -1
- data/Gemfile +2 -2
- data/README.md +2 -2
- data/active_model_serializers.gemspec +1 -1
- data/docs/general/serializers.md +16 -4
- data/lib/active_model/serializer.rb +20 -14
- data/lib/active_model/serializer/collection_serializer.rb +4 -6
- data/lib/active_model/serializer/lazy_association.rb +1 -0
- data/lib/active_model/serializer/link.rb +21 -0
- data/lib/active_model/serializer/reflection.rb +3 -0
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +18 -10
- data/lib/active_model_serializers/adapter/json_api.rb +12 -9
- data/lib/active_model_serializers/railtie.rb +2 -0
- data/test/action_controller/serialization_test.rb +9 -3
- data/test/adapter/json_api/links_test.rb +16 -1
- data/test/cache_test.rb +3 -3
- data/test/serializers/associations_test.rb +50 -0
- data/test/serializers/reflection_test.rb +52 -0
- metadata +56 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7232014fa13e7bf11951db024282a8518806ccdd81aead05ce694398e8f16439
|
4
|
+
data.tar.gz: 8337471a240ac4e1931fd71fbfbbf096e8bb5989ce51bce920d2f266aa0ac775
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33a114c6a2f87df622d820e8d04b9ce3099891a83f30527d93c159f0014a4fc3a60f883884b6d3a16fa4daf9f65cce1a57410eee4111391351c4199a73e8ca1c
|
7
|
+
data.tar.gz: 5ac71dcb57c2fd16b328cc849b948c6ae0d8cc6d409a1f0b3c942033c439e37c8c8fd8df3be5d80a8a153cb86e38d5cfe93a40fc553f09db739514759ca935a2
|
data/.travis.yml
CHANGED
@@ -40,6 +40,8 @@ matrix:
|
|
40
40
|
# - { rvm: jruby-head, jdk: oraclejdk8, env: "RAILS_VERSION=5.1 JRUBY_OPTS='--dev -J-Xmx1024M --debug'" }
|
41
41
|
exclude:
|
42
42
|
- { rvm: 2.1.10, env: RAILS_VERSION=master }
|
43
|
+
- { rvm: 2.2.8, env: RAILS_VERSION=master }
|
44
|
+
- { rvm: 2.3.5, env: RAILS_VERSION=master }
|
43
45
|
- { rvm: 2.1.10, env: RAILS_VERSION=5.0 }
|
44
46
|
- { rvm: 2.1.10, env: RAILS_VERSION=5.1 }
|
45
47
|
- { rvm: 2.4.2, env: RAILS_VERSION=4.1 }
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## 0.10.x
|
2
2
|
|
3
|
-
### [master (unreleased)](https://github.com/rails-api/active_model_serializers/compare/v0.10.
|
3
|
+
### [master (unreleased)](https://github.com/rails-api/active_model_serializers/compare/v0.10.8...0-10-stable)
|
4
4
|
|
5
5
|
Breaking changes:
|
6
6
|
|
@@ -8,8 +8,23 @@ Features:
|
|
8
8
|
|
9
9
|
Fixes:
|
10
10
|
|
11
|
+
|
11
12
|
Misc:
|
12
13
|
|
14
|
+
### [v0.10.8 (2018-11-01)](https://github.com/rails-api/active_model_serializers/compare/v0.10.7...v0.10.8)
|
15
|
+
|
16
|
+
Features:
|
17
|
+
- [#2279](https://github.com/rails-api/active_model_serializers/pull/2279) Support condition options in serializer link statements
|
18
|
+
|
19
|
+
Fixes:
|
20
|
+
|
21
|
+
- [#2296](https://github.com/rails-api/active_model_serializers/pull/2296) Fixes #2295 (@Hirurg103)
|
22
|
+
- Fix finding of namespaced serializer and non-namespaced model.
|
23
|
+
- [#2289](https://github.com/rails-api/active_model_serializers/pull/2289) Fixes #2255 (@f-mer)
|
24
|
+
- Fix autoloading race condition, especially in Rails 5.
|
25
|
+
- [#2299](https://github.com/rails-api/active_model_serializers/pull/2299) Fixes #2270 (@chau-bao-long via #2276)
|
26
|
+
- Fix reflection thread-safety bug
|
27
|
+
|
13
28
|
### [v0.10.7 (2017-11-14)](https://github.com/rails-api/active_model_serializers/compare/v0.10.6...v0.10.7)
|
14
29
|
|
15
30
|
Regressions Fixed From v0.10.6:
|
data/Gemfile
CHANGED
@@ -54,9 +54,9 @@ group :test do
|
|
54
54
|
gem 'sqlite3', platform: (@windows_platforms + [:ruby])
|
55
55
|
platforms :jruby do
|
56
56
|
if version == 'master' || version >= '5'
|
57
|
-
gem 'activerecord-jdbcsqlite3-adapter', '
|
57
|
+
gem 'activerecord-jdbcsqlite3-adapter', '~> 50'
|
58
58
|
else
|
59
|
-
gem 'activerecord-jdbcsqlite3-adapter'
|
59
|
+
gem 'activerecord-jdbcsqlite3-adapter', '~> 1.3.0'
|
60
60
|
end
|
61
61
|
end
|
62
62
|
gem 'codeclimate-test-reporter', require: false
|
data/README.md
CHANGED
@@ -266,8 +266,8 @@ to know about, but not part of ActiveModelSerializers.)
|
|
266
266
|
|
267
267
|
- An `ActiveRecord::Base` object.
|
268
268
|
- Any Ruby object that passes the
|
269
|
-
[Lint](
|
270
|
-
[code](
|
269
|
+
[Lint](https://www.rubydoc.info/gems/active_model_serializers/ActiveModel/Serializer/Lint/Tests)
|
270
|
+
[(code)](lib/active_model/serializer/lint.rb).
|
271
271
|
|
272
272
|
ActiveModelSerializers provides a
|
273
273
|
[`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb),
|
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
|
|
39
39
|
# 'activesupport', rails_versions
|
40
40
|
# 'i18n,
|
41
41
|
# 'tzinfo'
|
42
|
-
|
42
|
+
spec.add_development_dependency 'minitest', ['~> 5.0', '< 5.11']
|
43
43
|
# 'thread_safe'
|
44
44
|
|
45
45
|
spec.add_runtime_dependency 'jsonapi-renderer', ['>= 0.1.1.beta1', '< 0.3']
|
data/docs/general/serializers.md
CHANGED
@@ -65,7 +65,7 @@ Where:
|
|
65
65
|
- `virtual_value:`
|
66
66
|
- `polymorphic:` defines if polymorphic relation type should be nested in serialized association.
|
67
67
|
- `type:` the resource type as used by JSON:API, especially on a `belongs_to` relationship.
|
68
|
-
- `class_name:` used to determine `type
|
68
|
+
- `class_name:` the (String) model name used to determine `type`, when `type` is not given. e.g. `class_name: "Comment"` would imply the type `comments`
|
69
69
|
- `foreign_key:` used by JSON:API on a `belongs_to` relationship to avoid unnecessarily loading the association object.
|
70
70
|
- `namespace:` used when looking up the serializer and `serializer` is not given. Falls back to the parent serializer's `:namespace` instance options, which, when present, comes from the render options. See [Rendering#namespace](rendering.md#namespace] for more details.
|
71
71
|
- optional: `&block` is a context that returns the association's attributes.
|
@@ -81,6 +81,7 @@ e.g.
|
|
81
81
|
```ruby
|
82
82
|
has_one :bio
|
83
83
|
has_one :blog, key: :site
|
84
|
+
has_one :blog, class_name: "Blog"
|
84
85
|
has_one :maker, virtual_value: { id: 1 }
|
85
86
|
|
86
87
|
has_one :blog do |serializer|
|
@@ -114,6 +115,7 @@ e.g.
|
|
114
115
|
has_many :comments
|
115
116
|
has_many :comments, key: :reviews
|
116
117
|
has_many :comments, serializer: CommentPreviewSerializer
|
118
|
+
has_many :comments, class_name: "Comment"
|
117
119
|
has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]
|
118
120
|
has_many :comments, key: :last_comments do
|
119
121
|
last(1)
|
@@ -127,6 +129,7 @@ e.g.
|
|
127
129
|
```ruby
|
128
130
|
belongs_to :author, serializer: AuthorPreviewSerializer
|
129
131
|
belongs_to :author, key: :writer
|
132
|
+
belongs_to :author, class_name: "Author"
|
130
133
|
belongs_to :post
|
131
134
|
belongs_to :blog
|
132
135
|
def blog
|
@@ -235,6 +238,15 @@ link :other, 'https://example.com/resource'
|
|
235
238
|
link(:posts) { link_author_posts_url(object) }
|
236
239
|
```
|
237
240
|
|
241
|
+
Just like attributes, links also support conditions in options
|
242
|
+
```ruby
|
243
|
+
link(:secret, if: :internal?) { object.secret_link }
|
244
|
+
|
245
|
+
def internal?
|
246
|
+
instance_options[:context] == :internal
|
247
|
+
end
|
248
|
+
```
|
249
|
+
|
238
250
|
#### #object
|
239
251
|
|
240
252
|
The object being serialized.
|
@@ -294,7 +306,7 @@ end
|
|
294
306
|
Whether you write the method as above or as `object.comments.where(created_by: scope)`
|
295
307
|
is a matter of preference (assuming `scope_name` has been set).
|
296
308
|
|
297
|
-
Keep in mind that the scope can be set to any available controller reference. This can be utilized to provide access to any other data scopes or presentation helpers.
|
309
|
+
Keep in mind that the scope can be set to any available controller reference. This can be utilized to provide access to any other data scopes or presentation helpers.
|
298
310
|
|
299
311
|
##### Controller Authorization Context
|
300
312
|
|
@@ -381,7 +393,7 @@ class PostsController < ActionController::Base
|
|
381
393
|
end
|
382
394
|
end
|
383
395
|
```
|
384
|
-
Note that any controller reference which provides the desired scope is acceptable, such as another controller method for loading a different resource or reference to helpers. For example, `ActionController::API` does not include `ActionView::ViewContext`, and would need a different reference for passing any helpers into a serializer via `serialization_scope`.
|
396
|
+
Note that any controller reference which provides the desired scope is acceptable, such as another controller method for loading a different resource or reference to helpers. For example, `ActionController::API` does not include `ActionView::ViewContext`, and would need a different reference for passing any helpers into a serializer via `serialization_scope`.
|
385
397
|
|
386
398
|
#### #read_attribute_for_serialization(key)
|
387
399
|
|
@@ -474,7 +486,7 @@ the `ActiveModel::Serializer.serializer_for` method to return a serializer class
|
|
474
486
|
```ruby
|
475
487
|
class MySerializer < ActiveModel::Serializer
|
476
488
|
def self.serializer_for(model, options)
|
477
|
-
return SparseAdminSerializer if model.class == 'Admin'
|
489
|
+
return SparseAdminSerializer if model.class.name == 'Admin'
|
478
490
|
super
|
479
491
|
end
|
480
492
|
|
@@ -18,16 +18,17 @@ module ActiveModel
|
|
18
18
|
# @see #serializable_hash for more details on these valid keys.
|
19
19
|
SERIALIZABLE_HASH_VALID_KEYS = [:only, :except, :methods, :include, :root].freeze
|
20
20
|
extend ActiveSupport::Autoload
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
eager_autoload do
|
22
|
+
autoload :Adapter
|
23
|
+
autoload :Null
|
24
|
+
autoload :Attribute
|
25
|
+
autoload :Link
|
26
|
+
autoload :Association
|
27
|
+
autoload :Reflection
|
28
|
+
autoload :BelongsToReflection
|
29
|
+
autoload :HasOneReflection
|
30
|
+
autoload :HasManyReflection
|
31
|
+
end
|
31
32
|
include ActiveSupport::Configurable
|
32
33
|
include Caching
|
33
34
|
|
@@ -275,9 +276,14 @@ module ActiveModel
|
|
275
276
|
# link(:self) { "http://example.com/resource/#{object.id}" }
|
276
277
|
# @example
|
277
278
|
# link :resource, "http://example.com/resource"
|
279
|
+
# @example
|
280
|
+
# link(:callback, if: :internal?), { "http://example.com/callback" }
|
278
281
|
#
|
279
|
-
def self.link(name,
|
280
|
-
|
282
|
+
def self.link(name, *args, &block)
|
283
|
+
options = args.extract_options!
|
284
|
+
# For compatibility with the use case of passing link directly as string argument
|
285
|
+
# without block, we are creating a wrapping block
|
286
|
+
_links[name] = Link.new(name, options, block || ->(_serializer) { args.first })
|
281
287
|
end
|
282
288
|
|
283
289
|
# Set the JSON API meta attribute of a serializer.
|
@@ -341,7 +347,7 @@ module ActiveModel
|
|
341
347
|
return Enumerator.new {} unless object
|
342
348
|
|
343
349
|
Enumerator.new do |y|
|
344
|
-
self.class._reflections.each do |key, reflection|
|
350
|
+
(self.instance_reflections ||= self.class._reflections.deep_dup).each do |key, reflection|
|
345
351
|
next if reflection.excluded?(self)
|
346
352
|
next unless include_directive.key?(key)
|
347
353
|
|
@@ -405,6 +411,6 @@ module ActiveModel
|
|
405
411
|
|
406
412
|
protected
|
407
413
|
|
408
|
-
attr_accessor :instance_options
|
414
|
+
attr_accessor :instance_options, :instance_reflections
|
409
415
|
end
|
410
416
|
end
|
@@ -19,11 +19,10 @@ module ActiveModel
|
|
19
19
|
|
20
20
|
# @api private
|
21
21
|
def serializable_hash(adapter_options, options, adapter_instance)
|
22
|
-
include_directive
|
23
|
-
|
24
|
-
adapter_opts = adapter_options.merge(include_directive: include_directive)
|
22
|
+
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
|
23
|
+
options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(self, adapter_instance, options[:include_directive])
|
25
24
|
serializers.map do |serializer|
|
26
|
-
serializer.serializable_hash(
|
25
|
+
serializer.serializable_hash(adapter_options, options, adapter_instance)
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
@@ -48,8 +47,7 @@ module ActiveModel
|
|
48
47
|
# 4. key may be nil for empty collection and no serializer option
|
49
48
|
key &&= key.pluralize
|
50
49
|
# 5. fail if the key cannot be determined
|
51
|
-
key || fail(ArgumentError, 'Cannot infer root key from collection type. Please
|
52
|
-
specify the root or each_serializer option, or render a JSON String')
|
50
|
+
key || fail(ArgumentError, 'Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String')
|
53
51
|
end
|
54
52
|
# rubocop:enable Metrics/CyclomaticComplexity
|
55
53
|
|
@@ -76,6 +76,7 @@ module ActiveModel
|
|
76
76
|
serializer_options[:serializer_context_class] = association_options.fetch(:parent_serializer).class
|
77
77
|
serializer = reflection_options.fetch(:serializer, nil)
|
78
78
|
serializer_options[:serializer] = serializer if serializer
|
79
|
+
serializer_options[:namespace] = reflection_options[:namespace] if reflection_options[:namespace]
|
79
80
|
serializer_class.new(object, serializer_options)
|
80
81
|
end
|
81
82
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_model/serializer/field'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
class Serializer
|
5
|
+
# Holds all the data about a serializer link
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# class PostSerializer < ActiveModel::Serializer
|
9
|
+
# link :callback, if: :internal? do
|
10
|
+
# object.callback_link
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# def internal?
|
14
|
+
# instance_options[:internal] == true
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
class Link < Field
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -151,6 +151,9 @@ module ActiveModel
|
|
151
151
|
# @yield [ActiveModel::Serializer]
|
152
152
|
# @return [:nil, associated resource or resource collection]
|
153
153
|
def value(serializer, include_slice)
|
154
|
+
# NOTE(BF): This method isn't thread-safe because the _reflections class attribute is not thread-safe
|
155
|
+
# Therefore, when we build associations from reflections, we dup the entire reflection instance.
|
156
|
+
# Better solutions much appreciated!
|
154
157
|
@object = serializer.object
|
155
158
|
@scope = serializer.scope
|
156
159
|
|
@@ -5,16 +5,19 @@ require 'active_support/core_ext/string/inflections'
|
|
5
5
|
require 'active_support/json'
|
6
6
|
module ActiveModelSerializers
|
7
7
|
extend ActiveSupport::Autoload
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
eager_autoload do
|
9
|
+
autoload :Model
|
10
|
+
autoload :Callbacks
|
11
|
+
autoload :SerializableResource
|
12
|
+
autoload :SerializationContext
|
13
|
+
autoload :Logging
|
14
|
+
autoload :Test
|
15
|
+
autoload :Adapter
|
16
|
+
autoload :JsonPointer
|
17
|
+
autoload :Deprecate
|
18
|
+
autoload :LookupChain
|
19
|
+
autoload :Deserialization
|
20
|
+
end
|
18
21
|
|
19
22
|
class << self; attr_accessor :logger; end
|
20
23
|
self.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
|
@@ -46,6 +49,11 @@ module ActiveModelSerializers
|
|
46
49
|
$VERBOSE = original_verbose
|
47
50
|
end
|
48
51
|
|
52
|
+
def self.eager_load!
|
53
|
+
super
|
54
|
+
ActiveModel::Serializer.eager_load!
|
55
|
+
end
|
56
|
+
|
49
57
|
require 'active_model/serializer/version'
|
50
58
|
require 'active_model/serializer'
|
51
59
|
require 'active_model/serializable_resource'
|
@@ -22,14 +22,16 @@ module ActiveModelSerializers
|
|
22
22
|
module Adapter
|
23
23
|
class JsonApi < Base
|
24
24
|
extend ActiveSupport::Autoload
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
25
|
+
eager_autoload do
|
26
|
+
autoload :Jsonapi
|
27
|
+
autoload :ResourceIdentifier
|
28
|
+
autoload :Link
|
29
|
+
autoload :PaginationLinks
|
30
|
+
autoload :Meta
|
31
|
+
autoload :Error
|
32
|
+
autoload :Deserialization
|
33
|
+
autoload :Relationship
|
34
|
+
end
|
33
35
|
|
34
36
|
def self.default_key_transform
|
35
37
|
:dash
|
@@ -480,7 +482,8 @@ module ActiveModelSerializers
|
|
480
482
|
# }.reject! {|_,v| v.nil? }
|
481
483
|
def links_for(serializer)
|
482
484
|
serializer._links.each_with_object({}) do |(name, value), hash|
|
483
|
-
|
485
|
+
next if value.excluded?(serializer)
|
486
|
+
result = Link.new(serializer, value.block).as_json
|
484
487
|
hash[name] = result if result
|
485
488
|
end
|
486
489
|
end
|
@@ -457,13 +457,19 @@ module ActionController
|
|
457
457
|
end
|
458
458
|
|
459
459
|
def test_render_event_is_emitted
|
460
|
-
subscriber = ::ActiveSupport::Notifications.subscribe('render.active_model_serializers') do |
|
461
|
-
@
|
460
|
+
subscriber = ::ActiveSupport::Notifications.subscribe('render.active_model_serializers') do |subscribed_event|
|
461
|
+
@subscribed_event = subscribed_event
|
462
462
|
end
|
463
463
|
|
464
464
|
get :render_using_implicit_serializer
|
465
465
|
|
466
|
-
|
466
|
+
subscribed_event_name =
|
467
|
+
if @subscribed_event.is_a?(String)
|
468
|
+
@subscribed_event
|
469
|
+
else
|
470
|
+
@subscribed_event.name # is a ActiveSupport::Notifications::Event
|
471
|
+
end
|
472
|
+
assert_equal 'render.active_model_serializers', subscribed_event_name
|
467
473
|
ensure
|
468
474
|
ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
|
469
475
|
end
|
@@ -17,7 +17,21 @@ module ActiveModelSerializers
|
|
17
17
|
link :yet_another do
|
18
18
|
"http://example.com/resource/#{object.id}"
|
19
19
|
end
|
20
|
+
link :conditional1, if: -> { instance_truth } do
|
21
|
+
"http://example.com/conditional1/#{object.id}"
|
22
|
+
end
|
23
|
+
link :conditional2, if: :instance_falsey do
|
24
|
+
"http://example.com/conditional2/#{object.id}"
|
25
|
+
end
|
20
26
|
link(:nil) { nil }
|
27
|
+
|
28
|
+
def instance_truth
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def instance_falsey
|
33
|
+
false
|
34
|
+
end
|
21
35
|
end
|
22
36
|
|
23
37
|
def setup
|
@@ -85,7 +99,8 @@ module ActiveModelSerializers
|
|
85
99
|
:"link-authors" => 'http://example.com/link_authors',
|
86
100
|
resource: 'http://example.com/resource',
|
87
101
|
posts: 'http://example.com/link_authors/1337/posts',
|
88
|
-
:"yet-another" => 'http://example.com/resource/1337'
|
102
|
+
:"yet-another" => 'http://example.com/resource/1337',
|
103
|
+
conditional1: 'http://example.com/conditional1/1337'
|
89
104
|
}
|
90
105
|
assert_equal(expected, hash[:data][:links])
|
91
106
|
end
|
data/test/cache_test.rb
CHANGED
@@ -415,7 +415,7 @@ module ActiveModelSerializers
|
|
415
415
|
adapter_options = {}
|
416
416
|
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
417
417
|
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
418
|
-
cached_attributes =
|
418
|
+
cached_attributes = options.fetch(:cached_attributes).with_indifferent_access
|
419
419
|
|
420
420
|
include_directive = ActiveModelSerializers.default_include_directive
|
421
421
|
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive).with_indifferent_access
|
@@ -446,9 +446,9 @@ module ActiveModelSerializers
|
|
446
446
|
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
447
447
|
|
448
448
|
# Should find something with read_multi now
|
449
|
-
|
449
|
+
options = {}
|
450
450
|
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
451
|
-
cached_attributes =
|
451
|
+
cached_attributes = options.fetch(:cached_attributes)
|
452
452
|
|
453
453
|
include_directive = ActiveModelSerializers.default_include_directive
|
454
454
|
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
@@ -285,6 +285,56 @@ module ActiveModel
|
|
285
285
|
end
|
286
286
|
end
|
287
287
|
|
288
|
+
class AssociationsNamespacedSerializersTest < ActiveSupport::TestCase
|
289
|
+
class Post < ::Model
|
290
|
+
associations :comments, :author, :description
|
291
|
+
|
292
|
+
def latest_comments
|
293
|
+
comments[0..3]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
class Comment < ::Model; end
|
297
|
+
class Author < ::Model; end
|
298
|
+
class Description < ::Model; end
|
299
|
+
|
300
|
+
class ResourceNamespace
|
301
|
+
class PostSerializer < ActiveModel::Serializer
|
302
|
+
has_many :comments, namespace: ResourceNamespace
|
303
|
+
has_many :latest_comments, namespace: ResourceNamespace
|
304
|
+
belongs_to :author, namespace: ResourceNamespace
|
305
|
+
has_one :description, namespace: ResourceNamespace
|
306
|
+
end
|
307
|
+
class CommentSerializer < ActiveModel::Serializer; end
|
308
|
+
class AuthorSerializer < ActiveModel::Serializer; end
|
309
|
+
class DescriptionSerializer < ActiveModel::Serializer; end
|
310
|
+
end
|
311
|
+
|
312
|
+
def setup
|
313
|
+
@comment = Comment.new
|
314
|
+
@author = Author.new
|
315
|
+
@description = Description.new
|
316
|
+
@post = Post.new(comments: [@comment],
|
317
|
+
author: @author,
|
318
|
+
description: @description)
|
319
|
+
@post_serializer = ResourceNamespace::PostSerializer.new(@post)
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_associations_namespaced_serializers
|
323
|
+
@post_serializer.associations.each do |association|
|
324
|
+
case association.key
|
325
|
+
when :comments, :latest_comments
|
326
|
+
assert_instance_of(ResourceNamespace::CommentSerializer, association.lazy_association.serializer.first)
|
327
|
+
when :author
|
328
|
+
assert_instance_of(ResourceNamespace::AuthorSerializer, association.lazy_association.serializer)
|
329
|
+
when :description
|
330
|
+
assert_instance_of(ResourceNamespace::DescriptionSerializer, association.lazy_association.serializer)
|
331
|
+
else
|
332
|
+
flunk "Unknown association: #{key}"
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
288
338
|
class NestedSerializersTest < ActiveSupport::TestCase
|
289
339
|
class Post < ::Model
|
290
340
|
associations :comments, :author, :description
|
@@ -423,5 +423,57 @@ module ActiveModel
|
|
423
423
|
end
|
424
424
|
# rubocop:enable Metrics/AbcSize
|
425
425
|
end
|
426
|
+
class ThreadedReflectionTest < ActiveSupport::TestCase
|
427
|
+
class Post < ::Model
|
428
|
+
attributes :id, :title, :body
|
429
|
+
associations :comments
|
430
|
+
end
|
431
|
+
class Comment < ::Model
|
432
|
+
attributes :id, :body
|
433
|
+
associations :post
|
434
|
+
end
|
435
|
+
class CommentSerializer < ActiveModel::Serializer
|
436
|
+
type 'comment'
|
437
|
+
attributes :id, :body
|
438
|
+
has_one :post
|
439
|
+
end
|
440
|
+
class PostSerializer < ActiveModel::Serializer
|
441
|
+
type 'post'
|
442
|
+
attributes :id, :title, :body
|
443
|
+
has_many :comments, serializer: CommentSerializer do
|
444
|
+
sleep 0.1
|
445
|
+
object.comments
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
# per https://github.com/rails-api/active_model_serializers/issues/2270
|
450
|
+
def test_concurrent_serialization
|
451
|
+
post1 = Post.new(id: 1, title: 'Post 1 Title', body: 'Post 1 Body')
|
452
|
+
post1.comments = [Comment.new(id: 1, body: 'Comment on Post 1', post: post1)]
|
453
|
+
post2 = Post.new(id: 2, title: 'Post 2 Title', body: 'Post 2 Body')
|
454
|
+
post2.comments = [Comment.new(id: 2, body: 'Comment on Post 2', post: post2)]
|
455
|
+
serialized_posts = {
|
456
|
+
first: Set.new,
|
457
|
+
second: Set.new
|
458
|
+
}
|
459
|
+
t1 = Thread.new do
|
460
|
+
10.times do
|
461
|
+
serialized_posts[:first] << PostSerializer.new(post1, {}).to_json
|
462
|
+
end
|
463
|
+
end
|
464
|
+
t2 = Thread.new do
|
465
|
+
10.times do
|
466
|
+
serialized_posts[:second] << PostSerializer.new(post2, {}).to_json
|
467
|
+
end
|
468
|
+
end
|
469
|
+
t1.join
|
470
|
+
t2.join
|
471
|
+
expected_first_post_serialization = '{"id":1,"title":"Post 1 Title","body":"Post 1 Body","comments":[{"id":1,"body":"Comment on Post 1"}]}'
|
472
|
+
expected_second_post_serialization = '{"id":2,"title":"Post 2 Title","body":"Post 2 Body","comments":[{"id":2,"body":"Comment on Post 2"}]}'
|
473
|
+
|
474
|
+
assert_equal [expected_second_post_serialization], serialized_posts[:second].to_a
|
475
|
+
assert_equal [expected_first_post_serialization], serialized_posts[:first].to_a
|
476
|
+
end
|
477
|
+
end
|
426
478
|
end
|
427
479
|
end
|
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_model_serializers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Klabnik
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
+
name: activemodel
|
14
15
|
requirement: !ruby/object:Gem::Requirement
|
15
16
|
requirements:
|
16
17
|
- - ">="
|
@@ -19,9 +20,8 @@ dependencies:
|
|
19
20
|
- - "<"
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: '6'
|
22
|
-
name: activemodel
|
23
|
-
prerelease: false
|
24
23
|
type: :runtime
|
24
|
+
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
@@ -31,6 +31,7 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '6'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
+
name: actionpack
|
34
35
|
requirement: !ruby/object:Gem::Requirement
|
35
36
|
requirements:
|
36
37
|
- - ">="
|
@@ -39,9 +40,8 @@ dependencies:
|
|
39
40
|
- - "<"
|
40
41
|
- !ruby/object:Gem::Version
|
41
42
|
version: '6'
|
42
|
-
name: actionpack
|
43
|
-
prerelease: false
|
44
43
|
type: :runtime
|
44
|
+
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
@@ -51,6 +51,7 @@ dependencies:
|
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '6'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
|
+
name: railties
|
54
55
|
requirement: !ruby/object:Gem::Requirement
|
55
56
|
requirements:
|
56
57
|
- - ">="
|
@@ -59,9 +60,8 @@ dependencies:
|
|
59
60
|
- - "<"
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '6'
|
62
|
-
name: railties
|
63
|
-
prerelease: false
|
64
63
|
type: :development
|
64
|
+
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - ">="
|
@@ -71,6 +71,27 @@ dependencies:
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '6'
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
|
+
name: minitest
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '5.0'
|
80
|
+
- - "<"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.11'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.0'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '5.11'
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: jsonapi-renderer
|
74
95
|
requirement: !ruby/object:Gem::Requirement
|
75
96
|
requirements:
|
76
97
|
- - ">="
|
@@ -79,9 +100,8 @@ dependencies:
|
|
79
100
|
- - "<"
|
80
101
|
- !ruby/object:Gem::Version
|
81
102
|
version: '0.3'
|
82
|
-
name: jsonapi-renderer
|
83
|
-
prerelease: false
|
84
103
|
type: :runtime
|
104
|
+
prerelease: false
|
85
105
|
version_requirements: !ruby/object:Gem::Requirement
|
86
106
|
requirements:
|
87
107
|
- - ">="
|
@@ -91,20 +111,21 @@ dependencies:
|
|
91
111
|
- !ruby/object:Gem::Version
|
92
112
|
version: '0.3'
|
93
113
|
- !ruby/object:Gem::Dependency
|
114
|
+
name: case_transform
|
94
115
|
requirement: !ruby/object:Gem::Requirement
|
95
116
|
requirements:
|
96
117
|
- - ">="
|
97
118
|
- !ruby/object:Gem::Version
|
98
119
|
version: '0.2'
|
99
|
-
name: case_transform
|
100
|
-
prerelease: false
|
101
120
|
type: :runtime
|
121
|
+
prerelease: false
|
102
122
|
version_requirements: !ruby/object:Gem::Requirement
|
103
123
|
requirements:
|
104
124
|
- - ">="
|
105
125
|
- !ruby/object:Gem::Version
|
106
126
|
version: '0.2'
|
107
127
|
- !ruby/object:Gem::Dependency
|
128
|
+
name: activerecord
|
108
129
|
requirement: !ruby/object:Gem::Requirement
|
109
130
|
requirements:
|
110
131
|
- - ">="
|
@@ -113,9 +134,8 @@ dependencies:
|
|
113
134
|
- - "<"
|
114
135
|
- !ruby/object:Gem::Version
|
115
136
|
version: '6'
|
116
|
-
name: activerecord
|
117
|
-
prerelease: false
|
118
137
|
type: :development
|
138
|
+
prerelease: false
|
119
139
|
version_requirements: !ruby/object:Gem::Requirement
|
120
140
|
requirements:
|
121
141
|
- - ">="
|
@@ -125,20 +145,21 @@ dependencies:
|
|
125
145
|
- !ruby/object:Gem::Version
|
126
146
|
version: '6'
|
127
147
|
- !ruby/object:Gem::Dependency
|
148
|
+
name: kaminari
|
128
149
|
requirement: !ruby/object:Gem::Requirement
|
129
150
|
requirements:
|
130
151
|
- - "~>"
|
131
152
|
- !ruby/object:Gem::Version
|
132
153
|
version: 0.16.3
|
133
|
-
name: kaminari
|
134
|
-
prerelease: false
|
135
154
|
type: :development
|
155
|
+
prerelease: false
|
136
156
|
version_requirements: !ruby/object:Gem::Requirement
|
137
157
|
requirements:
|
138
158
|
- - "~>"
|
139
159
|
- !ruby/object:Gem::Version
|
140
160
|
version: 0.16.3
|
141
161
|
- !ruby/object:Gem::Dependency
|
162
|
+
name: will_paginate
|
142
163
|
requirement: !ruby/object:Gem::Requirement
|
143
164
|
requirements:
|
144
165
|
- - "~>"
|
@@ -147,9 +168,8 @@ dependencies:
|
|
147
168
|
- - ">="
|
148
169
|
- !ruby/object:Gem::Version
|
149
170
|
version: 3.0.7
|
150
|
-
name: will_paginate
|
151
|
-
prerelease: false
|
152
171
|
type: :development
|
172
|
+
prerelease: false
|
153
173
|
version_requirements: !ruby/object:Gem::Requirement
|
154
174
|
requirements:
|
155
175
|
- - "~>"
|
@@ -159,48 +179,49 @@ dependencies:
|
|
159
179
|
- !ruby/object:Gem::Version
|
160
180
|
version: 3.0.7
|
161
181
|
- !ruby/object:Gem::Dependency
|
182
|
+
name: bundler
|
162
183
|
requirement: !ruby/object:Gem::Requirement
|
163
184
|
requirements:
|
164
185
|
- - "~>"
|
165
186
|
- !ruby/object:Gem::Version
|
166
187
|
version: '1.6'
|
167
|
-
name: bundler
|
168
|
-
prerelease: false
|
169
188
|
type: :development
|
189
|
+
prerelease: false
|
170
190
|
version_requirements: !ruby/object:Gem::Requirement
|
171
191
|
requirements:
|
172
192
|
- - "~>"
|
173
193
|
- !ruby/object:Gem::Version
|
174
194
|
version: '1.6'
|
175
195
|
- !ruby/object:Gem::Dependency
|
196
|
+
name: simplecov
|
176
197
|
requirement: !ruby/object:Gem::Requirement
|
177
198
|
requirements:
|
178
199
|
- - "~>"
|
179
200
|
- !ruby/object:Gem::Version
|
180
201
|
version: '0.11'
|
181
|
-
name: simplecov
|
182
|
-
prerelease: false
|
183
202
|
type: :development
|
203
|
+
prerelease: false
|
184
204
|
version_requirements: !ruby/object:Gem::Requirement
|
185
205
|
requirements:
|
186
206
|
- - "~>"
|
187
207
|
- !ruby/object:Gem::Version
|
188
208
|
version: '0.11'
|
189
209
|
- !ruby/object:Gem::Dependency
|
210
|
+
name: timecop
|
190
211
|
requirement: !ruby/object:Gem::Requirement
|
191
212
|
requirements:
|
192
213
|
- - "~>"
|
193
214
|
- !ruby/object:Gem::Version
|
194
215
|
version: '0.7'
|
195
|
-
name: timecop
|
196
|
-
prerelease: false
|
197
216
|
type: :development
|
217
|
+
prerelease: false
|
198
218
|
version_requirements: !ruby/object:Gem::Requirement
|
199
219
|
requirements:
|
200
220
|
- - "~>"
|
201
221
|
- !ruby/object:Gem::Version
|
202
222
|
version: '0.7'
|
203
223
|
- !ruby/object:Gem::Dependency
|
224
|
+
name: grape
|
204
225
|
requirement: !ruby/object:Gem::Requirement
|
205
226
|
requirements:
|
206
227
|
- - ">="
|
@@ -209,9 +230,8 @@ dependencies:
|
|
209
230
|
- - "<"
|
210
231
|
- !ruby/object:Gem::Version
|
211
232
|
version: 0.19.1
|
212
|
-
name: grape
|
213
|
-
prerelease: false
|
214
233
|
type: :development
|
234
|
+
prerelease: false
|
215
235
|
version_requirements: !ruby/object:Gem::Requirement
|
216
236
|
requirements:
|
217
237
|
- - ">="
|
@@ -221,20 +241,21 @@ dependencies:
|
|
221
241
|
- !ruby/object:Gem::Version
|
222
242
|
version: 0.19.1
|
223
243
|
- !ruby/object:Gem::Dependency
|
244
|
+
name: json_schema
|
224
245
|
requirement: !ruby/object:Gem::Requirement
|
225
246
|
requirements:
|
226
247
|
- - ">="
|
227
248
|
- !ruby/object:Gem::Version
|
228
249
|
version: '0'
|
229
|
-
name: json_schema
|
230
|
-
prerelease: false
|
231
250
|
type: :development
|
251
|
+
prerelease: false
|
232
252
|
version_requirements: !ruby/object:Gem::Requirement
|
233
253
|
requirements:
|
234
254
|
- - ">="
|
235
255
|
- !ruby/object:Gem::Version
|
236
256
|
version: '0'
|
237
257
|
- !ruby/object:Gem::Dependency
|
258
|
+
name: rake
|
238
259
|
requirement: !ruby/object:Gem::Requirement
|
239
260
|
requirements:
|
240
261
|
- - ">="
|
@@ -243,9 +264,8 @@ dependencies:
|
|
243
264
|
- - "<"
|
244
265
|
- !ruby/object:Gem::Version
|
245
266
|
version: '12.0'
|
246
|
-
name: rake
|
247
|
-
prerelease: false
|
248
267
|
type: :development
|
268
|
+
prerelease: false
|
249
269
|
version_requirements: !ruby/object:Gem::Requirement
|
250
270
|
requirements:
|
251
271
|
- - ">="
|
@@ -333,6 +353,7 @@ files:
|
|
333
353
|
- lib/active_model/serializer/has_many_reflection.rb
|
334
354
|
- lib/active_model/serializer/has_one_reflection.rb
|
335
355
|
- lib/active_model/serializer/lazy_association.rb
|
356
|
+
- lib/active_model/serializer/link.rb
|
336
357
|
- lib/active_model/serializer/lint.rb
|
337
358
|
- lib/active_model/serializer/null.rb
|
338
359
|
- lib/active_model/serializer/reflection.rb
|
@@ -478,7 +499,7 @@ homepage: https://github.com/rails-api/active_model_serializers
|
|
478
499
|
licenses:
|
479
500
|
- MIT
|
480
501
|
metadata: {}
|
481
|
-
post_install_message:
|
502
|
+
post_install_message:
|
482
503
|
rdoc_options: []
|
483
504
|
require_paths:
|
484
505
|
- lib
|
@@ -493,9 +514,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
493
514
|
- !ruby/object:Gem::Version
|
494
515
|
version: '0'
|
495
516
|
requirements: []
|
496
|
-
rubyforge_project:
|
497
|
-
rubygems_version: 2.6
|
498
|
-
signing_key:
|
517
|
+
rubyforge_project:
|
518
|
+
rubygems_version: 2.7.6
|
519
|
+
signing_key:
|
499
520
|
specification_version: 4
|
500
521
|
summary: Conventions-based JSON generation for Rails.
|
501
522
|
test_files:
|