active_model_serializers 0.9.3 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +107 -0
  3. data/README.md +14 -13
  4. data/lib/action_controller/serialization.rb +9 -1
  5. data/lib/active_model/array_serializer.rb +4 -8
  6. data/lib/active_model/default_serializer.rb +2 -6
  7. data/lib/active_model/serializable.rb +12 -15
  8. data/lib/active_model/serializer.rb +25 -9
  9. data/lib/active_model/serializer/association/has_one.rb +1 -1
  10. data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +1 -1
  11. data/lib/active_model/serializer/railtie.rb +4 -0
  12. data/lib/active_model/serializer/version.rb +1 -1
  13. data/lib/active_model_serializers/model/caching.rb +25 -0
  14. data/test/benchmark/app.rb +60 -0
  15. data/test/benchmark/benchmarking_support.rb +67 -0
  16. data/test/benchmark/bm_active_record.rb +41 -0
  17. data/test/benchmark/setup.rb +75 -0
  18. data/test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25 +0 -0
  19. data/test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0 +0 -0
  20. data/test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c +0 -0
  21. data/test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48 +0 -0
  22. data/test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3 +0 -0
  23. data/test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0 +0 -0
  24. data/test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i +0 -0
  25. data/test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790 +0 -0
  26. data/test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj +0 -0
  27. data/test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1 +0 -0
  28. data/test/fixtures/active_record.rb +4 -0
  29. data/test/fixtures/poro.rb +46 -3
  30. data/test/integration/action_controller/namespaced_serialization_test.rb +10 -1
  31. data/test/integration/action_controller/serialization_test.rb +5 -5
  32. data/test/integration/active_record/active_record_test.rb +17 -0
  33. data/test/tmp/app/assets/javascripts/accounts.js +2 -0
  34. data/test/tmp/app/assets/stylesheets/accounts.css +4 -0
  35. data/test/tmp/app/controllers/accounts_controller.rb +2 -0
  36. data/test/tmp/app/helpers/accounts_helper.rb +2 -0
  37. data/test/{serializers/tmp → tmp}/app/serializers/account_serializer.rb +0 -0
  38. data/test/tmp/config/routes.rb +1 -0
  39. data/test/unit/active_model/array_serializer/options_test.rb +16 -0
  40. data/test/unit/active_model/array_serializer/serialization_test.rb +17 -0
  41. data/test/unit/active_model/serializer/associations_test.rb +30 -0
  42. data/test/unit/active_model/serializer/has_many_test.rb +1 -1
  43. data/test/unit/active_model/serializer/has_one_test.rb +14 -0
  44. data/test/unit/active_model/serializer/options_test.rb +8 -0
  45. data/test/unit/active_model/serilizable_test.rb +50 -0
  46. metadata +94 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 78c340a2e3f13f2c481239a485597b288d1bad45
4
- data.tar.gz: 41820649a307a90c8bcae4739e3dc32a77a45711
2
+ SHA256:
3
+ metadata.gz: e9f526564b9458ceea3d9391ddbf81cf996ff713dbb217bcec1c22931b4cd028
4
+ data.tar.gz: ac5641428e5b17ffa605bc7337f8f77000354a2a47f1a5ed7244ab50cdca84b2
5
5
  SHA512:
6
- metadata.gz: ef0646d4c09ba21a4a8182c9fa01931ba619faeeefbf0dfb1492fa5f8769b6ce5c6ac2962d13b09224943191cf70e79ab8e360da5923fadc1f5eaf8213c24ea1
7
- data.tar.gz: ab87b438037b55acf490d9ac6327abc01fed66cb06638bd12e235e0d3e3f8471a09144315762b866bba13958b60fa38dd02f9e9173d1dfff069ad310e02cec7b
6
+ metadata.gz: af47a8298fbc563716f0c7b4a9e0d92b85243ead1b0ccac561703d17f09574a3e65f280adedbb24ee7d65c0634c4ca343c58aa665628ff75d7e220b89025e91d
7
+ data.tar.gz: 6974a26799a967fbb8b172092be014deb775909a52cf10cf4e7dc88b5c05c96f6b6acbb3d245f9ad9032c743c2048c1afd8335d3a899c3111f2d6b48015800f7
@@ -1,3 +1,110 @@
1
+ ## 0.09.x
2
+
3
+ ### [0-9-stable](https://github.com/rails-api/active_model_serializers/compare/v0.9.8...0-9-stable)
4
+
5
+ ### [v0.9.8 (2020-12-10)](https://github.com/rails-api/active_model_serializers/compare/v0.9.7...v0.9.8)
6
+
7
+ - [#2373](https://github.com/rails-api/active_model_serializers/pull/2373) Fix Rails 6.0 deprecation warnings. (@supremebeing7)
8
+
9
+ ### [v0.9.7 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.9.6...v0.9.7)
10
+
11
+ - [#2080](https://github.com/rails-api/active_model_serializers/pull/2080) remove `{ payload: nil }` from `!serialize.active_model_serializers` ActiveSupport::Notification. `payload` never had a value. Changes, for example `{ serializer: 'ActiveModel::DefaultSerializer', payload: nil }` to be `{ serializer: 'ActiveModel::DefaultSerializer' }` (@yosiat)
12
+
13
+ ### [v0.9.6 (2017-01-10)](https://github.com/rails-api/active_model_serializers/compare/v0.9.5...v0.9.6)
14
+
15
+ - [#2008](https://github.com/rails-api/active_model_serializers/pull/2008) Fix warning on Thor. (@kirs)
16
+
17
+ ### [v0.9.5 (2016-03-30)](https://github.com/rails-api/active_model_serializers/compare/v0.9.4...v0.9.5)
18
+
19
+ - [#1607](https://github.com/rails-api/active_model_serializers/pull/1607) Merge multiple nested associations. (@Hirtenknogger)
20
+
21
+ ### [v0.9.4 (2016-01-05)](https://github.com/rails-api/active_model_serializers/compare/v0.9.3...v0.9.4)
22
+
23
+ - [#752](https://github.com/rails-api/active_model_serializers/pull/752) Tiny improvement of README 0-9-stable (@basiam)
24
+ - [#749](https://github.com/rails-api/active_model_serializers/pull/749) remove trailing whitespace (@shwoodard)
25
+ - [#717](https://github.com/rails-api/active_model_serializers/pull/717) fixed issue with rendering Hash which appears in rails 4.2.0.beta4 (@kurko, @greshny)
26
+ - [#790](https://github.com/rails-api/active_model_serializers/pull/790) pass context to ArraySerializer (@lanej)
27
+ - [#797](https://github.com/rails-api/active_model_serializers/pull/797) Fix and test for #490 (@afn)
28
+ - [#813](https://github.com/rails-api/active_model_serializers/pull/813) Allow to define custom serializer for given class (@jtomaszewski)
29
+ - [#841](https://github.com/rails-api/active_model_serializers/pull/841) Fix issue with embedding multiple associations under the same root key (@antstorm)
30
+ - [#748](https://github.com/rails-api/active_model_serializers/pull/748) Propagate serialization_options across associations (@raphaelpereira)
31
+
32
+ ### [v0.9.3 (2015/01/21 20:29 +00:00)](https://github.com/rails-api/active_model_serializers/compare/v0.9.2...v0.9.3)
33
+
34
+ Features:
35
+ - [#774](https://github.com/rails-api/active_model_serializers/pull/774) Fix nested include attributes (@nhocki)
36
+ - [#771](https://github.com/rails-api/active_model_serializers/pull/771) Make linked resource type names consistent with root names (@sweatypitts)
37
+ - [#696](https://github.com/rails-api/active_model_serializers/pull/696) Explicitly set serializer for associations (@ggordon)
38
+ - [#700](https://github.com/rails-api/active_model_serializers/pull/700) sparse fieldsets (@arenoir)
39
+ - [#768](https://github.com/rails-api/active_model_serializers/pull/768) Adds support for `meta` and `meta_key` attribute (@kurko)
40
+
41
+ ### [v0.9.2](https://github.com/rails-api/active_model_serializers/compare/v0.9.1...v0.9.2)
42
+
43
+ ### [v0.9.1 (2014/12/04 11:54 +00:00)](https://github.com/rails-api/active_model_serializers/compare/v0.9.0...v0.9.1)
44
+
45
+ - [#707](https://github.com/rails-api/active_model_serializers/pull/707) A Friendly Note on Which AMS Version to Use (@jherdman)
46
+ - [#730](https://github.com/rails-api/active_model_serializers/pull/730) Fixes nested has_many links in JSONAPI (@kurko)
47
+ - [#718](https://github.com/rails-api/active_model_serializers/pull/718) Allow overriding the adapter with render option (@ggordon)
48
+ - [#720](https://github.com/rails-api/active_model_serializers/pull/720) Rename attribute with :key (0.8.x compatibility) (@ggordon)
49
+ - [#728](https://github.com/rails-api/active_model_serializers/pull/728) Use type as key for linked resources (@kurko)
50
+ - [#729](https://github.com/rails-api/active_model_serializers/pull/729) Use the new beta build env on Travis (@joshk)
51
+ - [#703](https://github.com/rails-api/active_model_serializers/pull/703) Support serializer and each_serializer options in renderer (@ggordon, @mieko)
52
+ - [#727](https://github.com/rails-api/active_model_serializers/pull/727) Includes links inside of linked resources (@kurko)
53
+ - [#726](https://github.com/rails-api/active_model_serializers/pull/726) Bugfix: include nested has_many associations (@kurko)
54
+ - [#722](https://github.com/rails-api/active_model_serializers/pull/722) Fix infinite recursion (@ggordon)
55
+ - [#1](https://github.com/rails-api/active_model_serializers/pull/1) Allow for the implicit use of ArraySerializer when :each_serializer is specified (@mieko)
56
+ - [#692](https://github.com/rails-api/active_model_serializers/pull/692) Include 'linked' member for json-api collections (@ggordon)
57
+ - [#714](https://github.com/rails-api/active_model_serializers/pull/714) Define as_json instead of to_json (@guilleiguaran)
58
+ - [#710](https://github.com/rails-api/active_model_serializers/pull/710) JSON-API: Don't include linked section if associations are empty (@guilleiguaran)
59
+ - [#711](https://github.com/rails-api/active_model_serializers/pull/711) Fixes rbx gems bundling on TravisCI (@kurko)
60
+ - [#709](https://github.com/rails-api/active_model_serializers/pull/709) Add type key when association name is different than object type (@guilleiguaran)
61
+ - [#708](https://github.com/rails-api/active_model_serializers/pull/708) Handle correctly null associations (@guilleiguaran)
62
+ - [#691](https://github.com/rails-api/active_model_serializers/pull/691) Fix embed option for associations (@jacob-s-son)
63
+ - [#689](https://github.com/rails-api/active_model_serializers/pull/689) Fix support for custom root in JSON-API adapter (@guilleiguaran)
64
+ - [#685](https://github.com/rails-api/active_model_serializers/pull/685) Serialize ids as strings in JSON-API adapter (@guilleiguaran)
65
+ - [#684](https://github.com/rails-api/active_model_serializers/pull/684) Refactor adapters to implement support for array serialization (@guilleiguaran)
66
+ - [#682](https://github.com/rails-api/active_model_serializers/pull/682) Include root by default in JSON-API serializers (@guilleiguaran)
67
+ - [#625](https://github.com/rails-api/active_model_serializers/pull/625) Add DSL for urls (@JordanFaust)
68
+ - [#677](https://github.com/rails-api/active_model_serializers/pull/677) Add support for embed: :ids option for in associations (@guilleiguaran)
69
+ - [#681](https://github.com/rails-api/active_model_serializers/pull/681) Check superclasses for Serializers (@quainjn)
70
+ - [#680](https://github.com/rails-api/active_model_serializers/pull/680) Add support for root keys (@NullVoxPopuli)
71
+ - [#675](https://github.com/rails-api/active_model_serializers/pull/675) Support Rails 4.2.0 (@tricknotes)
72
+ - [#667](https://github.com/rails-api/active_model_serializers/pull/667) Require only activemodel instead of full rails (@guilleiguaran)
73
+ - [#653](https://github.com/rails-api/active_model_serializers/pull/653) Add "_test" suffix to JsonApi::HasManyTest filename. (@alexgenco)
74
+ - [#631](https://github.com/rails-api/active_model_serializers/pull/631) Update build badge URL (@craiglittle)
75
+
76
+ ### [v0.9.0](https://github.com/rails-api/active_model_serializers/compare/v0.9.0.alpha1...v0.9.0)
77
+
78
+ ### [0.9.0.alpha1 - January 7, 2014](https://github.com/rails-api/active_model_serializers/compare/d72b66d4c...v0.9.0.alpha1)
79
+
80
+ ### 0.9.0.pre
81
+
82
+ * The following methods were removed
83
+ - Model#active\_model\_serializer
84
+ - Serializer#include!
85
+ - Serializer#include?
86
+ - Serializer#attr\_disabled=
87
+ - Serializer#cache
88
+ - Serializer#perform\_caching
89
+ - Serializer#schema (needs more discussion)
90
+ - Serializer#attribute
91
+ - Serializer#include\_#{name}? (filter method added)
92
+ - Serializer#attributes (took a hash)
93
+
94
+ * The following things were added
95
+ - Serializer#filter method
96
+ - CONFIG object
97
+
98
+ * Remove support for ruby 1.8 versions.
99
+
100
+ * Require rails >= 3.2.
101
+
102
+ * Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
103
+
104
+ * Added a "prefix" option in case you want to use a different version of serializer.
105
+
106
+ * Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
107
+
1
108
  # VERSION 0.9.0.pre
2
109
 
3
110
  * The following methods were removed
data/README.md CHANGED
@@ -85,7 +85,7 @@ it exists, use it to serialize the `Post`.
85
85
 
86
86
  This also works with `respond_with`, which uses `to_json` under the hood. Also
87
87
  note that any options passed to `render :json` will be passed to your
88
- serializer and available as `@options` inside.
88
+ serializer and available as `@serialization_options` inside.
89
89
 
90
90
  To specify a custom serializer for an object, you can specify the
91
91
  serializer when you render the object:
@@ -251,11 +251,11 @@ BlogSerializer.new(object, key_format: :lower_camel)
251
251
 
252
252
  You can specify that serializers use unsuffixed names as association keys by default.
253
253
 
254
- `````ruby
254
+ ```ruby
255
255
  ActiveModel::Serializer.setup do |config|
256
256
  config.default_key_type = :name
257
257
  end
258
- ````
258
+ ```
259
259
 
260
260
  This will build association keys like `comments` or `author` instead of `comment_ids` or `author_id`.
261
261
 
@@ -339,6 +339,7 @@ And it's also safe to mutate keys argument by doing keys.delete(:author)
339
339
  in case you want to avoid creating two extra arrays. Note that if you do an
340
340
  in-place modification, you still need to return the modified array.
341
341
 
342
+ ### Alias Attribute
342
343
  If you would like the key in the outputted JSON to be different from its name
343
344
  in ActiveRecord, you can declare the attribute with the different name
344
345
  and redefine that method:
@@ -377,7 +378,7 @@ The above usage of `:meta` will produce the following:
377
378
  If you would like to change the meta key name you can use the `:meta_key` option:
378
379
 
379
380
  ```ruby
380
- render json: @posts, serializer: CustomArraySerializer, meta_object: {total: 10}, meta_key: 'meta_object'
381
+ render json: @posts, serializer: CustomArraySerializer, meta_object: { total: 10 }, meta_key: :meta_object
381
382
  ```
382
383
 
383
384
  The above usage of `:meta_key` will produce the following:
@@ -755,18 +756,18 @@ end
755
756
  "title": "New post",
756
757
  "attachments": [
757
758
  {
758
- "type": "image"
759
+ "type": "image",
759
760
  "image": {
760
- "id": 3
761
- "name": "logo"
761
+ "id": 3,
762
+ "name": "logo",
762
763
  "url": "http://images.com/logo.jpg"
763
764
  }
764
765
  },
765
766
  {
766
- "type": "video"
767
+ "type": "video",
767
768
  "video": {
768
- "id": 12
769
- "uid": "XCSSMDFWW"
769
+ "id": 12,
770
+ "uid": "XCSSMDFWW",
770
771
  "source": "youtube"
771
772
  }
772
773
  }
@@ -793,11 +794,11 @@ end
793
794
  "title": "New post",
794
795
  "attachment_ids": [
795
796
  {
796
- "type": "image"
797
+ "type": "image",
797
798
  "id": 12
798
799
  },
799
800
  {
800
- "type": "video"
801
+ "type": "video",
801
802
  "id": 3
802
803
  }
803
804
  ]
@@ -931,7 +932,7 @@ now generates:
931
932
  class PostSerializer < ApplicationSerializer
932
933
  attributes :id
933
934
  end
934
- ````
935
+ ```
935
936
 
936
937
  # Design and Implementation Guidelines
937
938
 
@@ -60,7 +60,15 @@ module ActionController
60
60
  private
61
61
 
62
62
  def namespace_for_serializer
63
- @namespace_for_serializer ||= self.class.parent unless self.class.parent == Object
63
+ @namespace_for_serializer ||= namespace_for_class(self.class) unless namespace_for_class(self.class) == Object
64
+ end
65
+
66
+ def namespace_for_class(klass)
67
+ if Module.method_defined?(:module_parent)
68
+ klass.module_parent
69
+ else
70
+ klass.parent
71
+ end
64
72
  end
65
73
 
66
74
  def default_serializer(resource)
@@ -15,17 +15,18 @@ module ActiveModel
15
15
  @object = object
16
16
  @scope = options[:scope]
17
17
  @root = options.fetch(:root, self.class._root)
18
- @polymorphic = options.fetch(:polymorphic, false)
18
+ @polymorphic = options.fetch(:polymorphic, false)
19
19
  @meta_key = options[:meta_key] || :meta
20
20
  @meta = options[@meta_key]
21
21
  @each_serializer = options[:each_serializer]
22
22
  @resource_name = options[:resource_name]
23
23
  @only = options[:only] ? Array(options[:only]) : nil
24
24
  @except = options[:except] ? Array(options[:except]) : nil
25
+ @context = options[:context]
25
26
  @namespace = options[:namespace]
26
27
  @key_format = options[:key_format] || options[:each_serializer].try(:key_format)
27
28
  end
28
- attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format
29
+ attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context
29
30
 
30
31
  def json_key
31
32
  key = root.nil? ? @resource_name : root
@@ -35,7 +36,7 @@ module ActiveModel
35
36
 
36
37
  def serializer_for(item)
37
38
  serializer_class = @each_serializer || Serializer.serializer_for(item, namespace: @namespace) || DefaultSerializer
38
- serializer_class.new(item, scope: scope, key_format: key_format, only: @only, except: @except, polymorphic: @polymorphic, namespace: @namespace)
39
+ serializer_class.new(item, scope: scope, key_format: key_format, context: @context, only: @only, except: @except, polymorphic: @polymorphic, namespace: @namespace)
39
40
  end
40
41
 
41
42
  def serializable_object(options={})
@@ -63,10 +64,5 @@ module ActiveModel
63
64
  end
64
65
  end
65
66
 
66
- private
67
-
68
- def instrumentation_keys
69
- [:object, :scope, :root, :meta_key, :meta, :each_serializer, :resource_name, :key_format]
70
- end
71
67
  end
72
68
  end
@@ -15,18 +15,14 @@ module ActiveModel
15
15
  end
16
16
 
17
17
  def as_json(options={})
18
- instrument('!serialize') do
18
+ instrument do
19
19
  return [] if @object.nil? && @wrap_in_array
20
20
  hash = @object.as_json
21
21
  @wrap_in_array ? [hash] : hash
22
22
  end
23
23
  end
24
+
24
25
  alias serializable_hash as_json
25
26
  alias serializable_object as_json
26
-
27
- private
28
- def instrumentation_keys
29
- [:object, :wrap_in_array]
30
- end
31
27
  end
32
28
  end
@@ -2,12 +2,14 @@ require 'active_model/serializable/utils'
2
2
 
3
3
  module ActiveModel
4
4
  module Serializable
5
+ INSTRUMENTATION_KEY = '!serialize.active_model_serializers'.freeze
6
+
5
7
  def self.included(base)
6
8
  base.extend Utils
7
9
  end
8
10
 
9
11
  def as_json(options={})
10
- instrument('!serialize') do
12
+ instrument do
11
13
  if root = options.fetch(:root, json_key)
12
14
  hash = { root => serializable_object(options) }
13
15
  hash.merge!(serializable_data)
@@ -19,9 +21,7 @@ module ActiveModel
19
21
  end
20
22
 
21
23
  def serializable_object_with_notification(options={})
22
- instrument('!serialize') do
23
- serializable_object(options)
24
- end
24
+ instrument { serializable_object(options) }
25
25
  end
26
26
 
27
27
  def serializable_data
@@ -33,7 +33,11 @@ module ActiveModel
33
33
  end
34
34
 
35
35
  def namespace
36
- get_namespace && Utils._const_get(get_namespace)
36
+ if module_name = get_namespace
37
+ Serializer.serializers_cache.fetch_or_store(module_name) do
38
+ Utils._const_get(module_name)
39
+ end
40
+ end
37
41
  end
38
42
 
39
43
  def embedded_in_root_associations
@@ -47,16 +51,9 @@ module ActiveModel
47
51
  modules[0..-2].join('::') if modules.size > 1
48
52
  end
49
53
 
50
- def instrument(action, &block)
51
- payload = instrumentation_keys.inject({ serializer: self.class.name }) do |payload, key|
52
- payload[:payload] = self.instance_variable_get(:"@#{key}")
53
- payload
54
- end
55
- ActiveSupport::Notifications.instrument("#{action}.active_model_serializers", payload, &block)
56
- end
57
-
58
- def instrumentation_keys
59
- [:object, :scope, :root, :meta_key, :meta, :wrap_in_array, :only, :except, :key_format]
54
+ def instrument(&block)
55
+ payload = { serializer: self.class.name }
56
+ ActiveSupport::Notifications.instrument(INSTRUMENTATION_KEY, payload, &block)
60
57
  end
61
58
  end
62
59
  end
@@ -4,6 +4,7 @@ require 'active_model/serializer/association'
4
4
  require 'active_model/serializer/config'
5
5
 
6
6
  require 'thread'
7
+ require 'concurrent/map'
7
8
 
8
9
  module ActiveModel
9
10
  class Serializer
@@ -56,14 +57,19 @@ end
56
57
  attr_reader :key_format
57
58
 
58
59
  def serializer_for(resource, options = {})
59
- if resource.respond_to?(:to_ary)
60
+ if resource.respond_to?(:serializer_class)
61
+ resource.serializer_class
62
+ elsif resource.respond_to?(:to_ary)
60
63
  if Object.constants.include?(:ArraySerializer)
61
64
  ::ArraySerializer
62
65
  else
63
66
  ArraySerializer
64
67
  end
65
68
  else
66
- _const_get build_serializer_class(resource, options)
69
+ klass_name = build_serializer_class(resource, options)
70
+ Serializer.serializers_cache.fetch_or_store(klass_name) do
71
+ _const_get(klass_name)
72
+ end
67
73
  end
68
74
  end
69
75
 
@@ -98,6 +104,10 @@ end
98
104
  associate(Association::HasMany, *attrs)
99
105
  end
100
106
 
107
+ def serializers_cache
108
+ @serializers_cache ||= Concurrent::Map.new
109
+ end
110
+
101
111
  private
102
112
 
103
113
  def strip_attribute(attr)
@@ -161,7 +171,7 @@ end
161
171
  end
162
172
  end
163
173
 
164
- def associations
174
+ def associations(options={})
165
175
  associations = self.class._associations
166
176
  included_associations = filter(associations.keys)
167
177
  associations.each_with_object({}) do |(name, association), hash|
@@ -178,7 +188,7 @@ end
178
188
  if association.embed_namespace?
179
189
  hash = hash[association.embed_namespace] ||= {}
180
190
  end
181
- hash[association.embedded_key] = serialize association
191
+ hash[association.embedded_key] = serialize association, options
182
192
  end
183
193
  end
184
194
  end
@@ -201,8 +211,14 @@ end
201
211
  if included_associations.include? name
202
212
  association_serializer = build_serializer(association)
203
213
  # we must do this always because even if the current association is not
204
- # embeded in root, it might have its own associations that are embeded in root
205
- hash.merge!(association_serializer.embedded_in_root_associations) {|key, oldval, newval| [newval, oldval].flatten }
214
+ # embedded in root, it might have its own associations that are embedded in root
215
+ hash.merge!(association_serializer.embedded_in_root_associations) do |key, oldval, newval|
216
+ if oldval.respond_to?(:to_ary)
217
+ [oldval, newval].flatten.uniq
218
+ else
219
+ oldval.merge(newval) { |_, oldval, newval| [oldval, newval].flatten.uniq }
220
+ end
221
+ end
206
222
 
207
223
  if association.embed_in_root?
208
224
  if association.embed_in_root_key?
@@ -236,8 +252,8 @@ end
236
252
  end
237
253
  end
238
254
 
239
- def serialize(association)
240
- build_serializer(association).serializable_object
255
+ def serialize(association,options={})
256
+ build_serializer(association).serializable_object(options)
241
257
  end
242
258
 
243
259
  def serialize_ids(association)
@@ -282,7 +298,7 @@ end
282
298
  self.serialization_options = options
283
299
  return @wrap_in_array ? [] : nil if @object.nil?
284
300
  hash = attributes
285
- hash.merge! associations
301
+ hash.merge! associations(options)
286
302
  hash = convert_keys(hash) if key_format.present?
287
303
  hash = { :type => type_name(@object), type_name(@object) => hash } if @polymorphic
288
304
  @wrap_in_array ? [hash] : hash
@@ -12,7 +12,7 @@ module ActiveModel
12
12
  end
13
13
 
14
14
  def serializer_class(object, options = {})
15
- serializer_from_options || serializer_from_object(object, options) || default_serializer
15
+ (serializer_from_options unless object.nil?) || serializer_from_object(object, options) || default_serializer
16
16
  end
17
17
 
18
18
  def build_serializer(object, options = {})