active_model_serializers 0.10.7 → 0.10.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.
- 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:
|