active_model_serializers 0.10.3 → 0.10.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +154 -2
  3. data/README.md +153 -15
  4. data/lib/action_controller/serialization.rb +11 -1
  5. data/lib/active_model/serializable_resource.rb +2 -0
  6. data/lib/active_model/serializer.rb +275 -81
  7. data/lib/active_model/serializer/adapter.rb +2 -0
  8. data/lib/active_model/serializer/adapter/attributes.rb +2 -0
  9. data/lib/active_model/serializer/adapter/base.rb +2 -0
  10. data/lib/active_model/serializer/adapter/json.rb +2 -0
  11. data/lib/active_model/serializer/adapter/json_api.rb +2 -0
  12. data/lib/active_model/serializer/adapter/null.rb +2 -0
  13. data/lib/active_model/serializer/array_serializer.rb +2 -0
  14. data/lib/active_model/serializer/association.rb +53 -14
  15. data/lib/active_model/serializer/attribute.rb +2 -0
  16. data/lib/active_model/serializer/belongs_to_reflection.rb +7 -1
  17. data/lib/active_model/serializer/collection_serializer.rb +8 -5
  18. data/lib/active_model/serializer/concerns/caching.rb +36 -23
  19. data/lib/active_model/serializer/error_serializer.rb +2 -0
  20. data/lib/active_model/serializer/errors_serializer.rb +2 -0
  21. data/lib/active_model/serializer/field.rb +2 -0
  22. data/lib/active_model/serializer/fieldset.rb +3 -1
  23. data/lib/active_model/serializer/has_many_reflection.rb +6 -1
  24. data/lib/active_model/serializer/has_one_reflection.rb +3 -1
  25. data/lib/active_model/serializer/lazy_association.rb +99 -0
  26. data/lib/active_model/serializer/link.rb +23 -0
  27. data/lib/active_model/serializer/lint.rb +2 -0
  28. data/lib/active_model/serializer/null.rb +2 -0
  29. data/lib/active_model/serializer/reflection.rb +122 -73
  30. data/lib/active_model/serializer/version.rb +3 -1
  31. data/lib/active_model_serializers.rb +29 -11
  32. data/lib/active_model_serializers/adapter.rb +3 -1
  33. data/lib/active_model_serializers/adapter/attributes.rb +23 -0
  34. data/lib/active_model_serializers/adapter/base.rb +4 -2
  35. data/lib/active_model_serializers/adapter/json.rb +2 -0
  36. data/lib/active_model_serializers/adapter/json_api.rb +44 -26
  37. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
  38. data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
  39. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
  40. data/lib/active_model_serializers/adapter/json_api/link.rb +2 -0
  41. data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
  42. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +42 -21
  43. data/lib/active_model_serializers/adapter/json_api/relationship.rb +52 -9
  44. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +35 -18
  45. data/lib/active_model_serializers/adapter/null.rb +2 -0
  46. data/lib/active_model_serializers/callbacks.rb +2 -0
  47. data/lib/active_model_serializers/deprecate.rb +2 -0
  48. data/lib/active_model_serializers/deserialization.rb +2 -0
  49. data/lib/active_model_serializers/json_pointer.rb +2 -0
  50. data/lib/active_model_serializers/logging.rb +2 -0
  51. data/lib/active_model_serializers/lookup_chain.rb +2 -0
  52. data/lib/active_model_serializers/model.rb +111 -30
  53. data/lib/active_model_serializers/model/caching.rb +25 -0
  54. data/lib/active_model_serializers/railtie.rb +4 -0
  55. data/lib/active_model_serializers/register_jsonapi_renderer.rb +2 -0
  56. data/lib/active_model_serializers/serializable_resource.rb +4 -2
  57. data/lib/active_model_serializers/serialization_context.rb +2 -0
  58. data/lib/active_model_serializers/test.rb +2 -0
  59. data/lib/active_model_serializers/test/schema.rb +4 -2
  60. data/lib/active_model_serializers/test/serializer.rb +2 -0
  61. data/lib/generators/rails/resource_override.rb +3 -1
  62. data/lib/generators/rails/serializer_generator.rb +2 -0
  63. data/lib/grape/active_model_serializers.rb +2 -0
  64. data/lib/grape/formatters/active_model_serializers.rb +2 -0
  65. data/lib/grape/helpers/active_model_serializers.rb +2 -0
  66. data/lib/tasks/rubocop.rake +55 -0
  67. metadata +74 -291
  68. data/.github/ISSUE_TEMPLATE.md +0 -29
  69. data/.github/PULL_REQUEST_TEMPLATE.md +0 -15
  70. data/.gitignore +0 -35
  71. data/.rubocop.yml +0 -102
  72. data/.simplecov +0 -110
  73. data/.travis.yml +0 -51
  74. data/CODE_OF_CONDUCT.md +0 -74
  75. data/CONTRIBUTING.md +0 -105
  76. data/Gemfile +0 -56
  77. data/Rakefile +0 -103
  78. data/active_model_serializers.gemspec +0 -62
  79. data/appveyor.yml +0 -24
  80. data/bin/bench +0 -171
  81. data/bin/bench_regression +0 -316
  82. data/bin/serve_benchmark +0 -39
  83. data/docs/ARCHITECTURE.md +0 -125
  84. data/docs/README.md +0 -42
  85. data/docs/STYLE.md +0 -58
  86. data/docs/general/adapters.md +0 -247
  87. data/docs/general/caching.md +0 -58
  88. data/docs/general/configuration_options.md +0 -169
  89. data/docs/general/deserialization.md +0 -100
  90. data/docs/general/fields.md +0 -31
  91. data/docs/general/getting_started.md +0 -133
  92. data/docs/general/instrumentation.md +0 -40
  93. data/docs/general/key_transforms.md +0 -40
  94. data/docs/general/logging.md +0 -14
  95. data/docs/general/rendering.md +0 -294
  96. data/docs/general/serializers.md +0 -461
  97. data/docs/how-open-source-maintained.jpg +0 -0
  98. data/docs/howto/add_pagination_links.md +0 -138
  99. data/docs/howto/add_relationship_links.md +0 -137
  100. data/docs/howto/add_root_key.md +0 -55
  101. data/docs/howto/grape_integration.md +0 -42
  102. data/docs/howto/outside_controller_use.md +0 -65
  103. data/docs/howto/passing_arbitrary_options.md +0 -27
  104. data/docs/howto/serialize_poro.md +0 -32
  105. data/docs/howto/test.md +0 -154
  106. data/docs/howto/upgrade_from_0_8_to_0_10.md +0 -265
  107. data/docs/integrations/ember-and-json-api.md +0 -144
  108. data/docs/integrations/grape.md +0 -19
  109. data/docs/jsonapi/errors.md +0 -56
  110. data/docs/jsonapi/schema.md +0 -151
  111. data/docs/jsonapi/schema/schema.json +0 -366
  112. data/docs/rfcs/0000-namespace.md +0 -106
  113. data/docs/rfcs/template.md +0 -15
  114. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  115. data/lib/active_model/serializer/concerns/associations.rb +0 -102
  116. data/lib/active_model/serializer/concerns/attributes.rb +0 -82
  117. data/lib/active_model/serializer/concerns/configuration.rb +0 -59
  118. data/lib/active_model/serializer/concerns/links.rb +0 -35
  119. data/lib/active_model/serializer/concerns/meta.rb +0 -29
  120. data/lib/active_model/serializer/concerns/type.rb +0 -25
  121. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  122. data/lib/active_model_serializers/key_transform.rb +0 -74
  123. data/test/action_controller/adapter_selector_test.rb +0 -53
  124. data/test/action_controller/explicit_serializer_test.rb +0 -135
  125. data/test/action_controller/json/include_test.rb +0 -246
  126. data/test/action_controller/json_api/deserialization_test.rb +0 -112
  127. data/test/action_controller/json_api/errors_test.rb +0 -40
  128. data/test/action_controller/json_api/fields_test.rb +0 -57
  129. data/test/action_controller/json_api/linked_test.rb +0 -202
  130. data/test/action_controller/json_api/pagination_test.rb +0 -116
  131. data/test/action_controller/json_api/transform_test.rb +0 -181
  132. data/test/action_controller/lookup_proc_test.rb +0 -49
  133. data/test/action_controller/namespace_lookup_test.rb +0 -226
  134. data/test/action_controller/serialization_scope_name_test.rb +0 -229
  135. data/test/action_controller/serialization_test.rb +0 -472
  136. data/test/active_model_serializers/adapter_for_test.rb +0 -208
  137. data/test/active_model_serializers/json_pointer_test.rb +0 -22
  138. data/test/active_model_serializers/key_transform_test.rb +0 -297
  139. data/test/active_model_serializers/logging_test.rb +0 -77
  140. data/test/active_model_serializers/model_test.rb +0 -22
  141. data/test/active_model_serializers/railtie_test_isolated.rb +0 -63
  142. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +0 -143
  143. data/test/active_model_serializers/serialization_context_test_isolated.rb +0 -71
  144. data/test/active_model_serializers/test/schema_test.rb +0 -130
  145. data/test/active_model_serializers/test/serializer_test.rb +0 -62
  146. data/test/active_record_test.rb +0 -9
  147. data/test/adapter/attributes_test.rb +0 -43
  148. data/test/adapter/deprecation_test.rb +0 -100
  149. data/test/adapter/json/belongs_to_test.rb +0 -45
  150. data/test/adapter/json/collection_test.rb +0 -104
  151. data/test/adapter/json/has_many_test.rb +0 -45
  152. data/test/adapter/json/transform_test.rb +0 -93
  153. data/test/adapter/json_api/belongs_to_test.rb +0 -155
  154. data/test/adapter/json_api/collection_test.rb +0 -96
  155. data/test/adapter/json_api/errors_test.rb +0 -76
  156. data/test/adapter/json_api/fields_test.rb +0 -88
  157. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  158. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +0 -96
  159. data/test/adapter/json_api/has_many_test.rb +0 -165
  160. data/test/adapter/json_api/has_one_test.rb +0 -80
  161. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +0 -166
  162. data/test/adapter/json_api/json_api_test.rb +0 -33
  163. data/test/adapter/json_api/linked_test.rb +0 -413
  164. data/test/adapter/json_api/links_test.rb +0 -95
  165. data/test/adapter/json_api/pagination_links_test.rb +0 -193
  166. data/test/adapter/json_api/parse_test.rb +0 -137
  167. data/test/adapter/json_api/relationship_test.rb +0 -397
  168. data/test/adapter/json_api/resource_identifier_test.rb +0 -110
  169. data/test/adapter/json_api/resource_meta_test.rb +0 -100
  170. data/test/adapter/json_api/toplevel_jsonapi_test.rb +0 -82
  171. data/test/adapter/json_api/transform_test.rb +0 -504
  172. data/test/adapter/json_api/type_test.rb +0 -61
  173. data/test/adapter/json_test.rb +0 -46
  174. data/test/adapter/null_test.rb +0 -22
  175. data/test/adapter/polymorphic_test.rb +0 -171
  176. data/test/adapter_test.rb +0 -67
  177. data/test/array_serializer_test.rb +0 -22
  178. data/test/benchmark/app.rb +0 -65
  179. data/test/benchmark/benchmarking_support.rb +0 -67
  180. data/test/benchmark/bm_active_record.rb +0 -81
  181. data/test/benchmark/bm_adapter.rb +0 -38
  182. data/test/benchmark/bm_caching.rb +0 -119
  183. data/test/benchmark/bm_lookup_chain.rb +0 -83
  184. data/test/benchmark/bm_transform.rb +0 -45
  185. data/test/benchmark/config.ru +0 -3
  186. data/test/benchmark/controllers.rb +0 -83
  187. data/test/benchmark/fixtures.rb +0 -219
  188. data/test/cache_test.rb +0 -579
  189. data/test/collection_serializer_test.rb +0 -110
  190. data/test/fixtures/active_record.rb +0 -78
  191. data/test/fixtures/poro.rb +0 -286
  192. data/test/generators/scaffold_controller_generator_test.rb +0 -24
  193. data/test/generators/serializer_generator_test.rb +0 -74
  194. data/test/grape_test.rb +0 -178
  195. data/test/lint_test.rb +0 -49
  196. data/test/logger_test.rb +0 -20
  197. data/test/poro_test.rb +0 -9
  198. data/test/serializable_resource_test.rb +0 -79
  199. data/test/serializers/association_macros_test.rb +0 -37
  200. data/test/serializers/associations_test.rb +0 -370
  201. data/test/serializers/attribute_test.rb +0 -151
  202. data/test/serializers/attributes_test.rb +0 -52
  203. data/test/serializers/caching_configuration_test_isolated.rb +0 -170
  204. data/test/serializers/configuration_test.rb +0 -32
  205. data/test/serializers/fieldset_test.rb +0 -14
  206. data/test/serializers/meta_test.rb +0 -202
  207. data/test/serializers/options_test.rb +0 -21
  208. data/test/serializers/read_attribute_for_serialization_test.rb +0 -79
  209. data/test/serializers/root_test.rb +0 -21
  210. data/test/serializers/serialization_test.rb +0 -55
  211. data/test/serializers/serializer_for_test.rb +0 -136
  212. data/test/serializers/serializer_for_with_namespace_test.rb +0 -87
  213. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  214. data/test/support/isolated_unit.rb +0 -82
  215. data/test/support/rails5_shims.rb +0 -53
  216. data/test/support/rails_app.rb +0 -36
  217. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  218. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +0 -6
  219. data/test/support/schemas/custom/show.json +0 -7
  220. data/test/support/schemas/hyper_schema.json +0 -93
  221. data/test/support/schemas/render_using_json_api.json +0 -43
  222. data/test/support/schemas/simple_json_pointers.json +0 -10
  223. data/test/support/serialization_testing.rb +0 -71
  224. data/test/test_helper.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c59f59688a0f1097d51eecd56caa45fc9ccec6e0
4
- data.tar.gz: 5907cb2c75b806f2ac46b9457a33e898d10dc4a1
2
+ SHA256:
3
+ metadata.gz: 3c046246492aa51d55bec5b8ce5d2a97d9cd0ff8dba206cdde613f47aca0230e
4
+ data.tar.gz: 3621cbc3e965bc80389e08b40483b6de73e4a7c7ba7ac96315e1d6e5ee2995e9
5
5
  SHA512:
6
- metadata.gz: 540883101bd1555c3697cae38658e773c726a42d8195d6f9f59f928cfe3bf5105c91f3c8fd48c88e83e4d2f288ebd03b07f74d9747ca66fc281d50f82b2983eb
7
- data.tar.gz: 208b3eb1c115cb2c18dce647371e9748576bee1a440c4e7b9edc1e5730e145096bb722c999cd37b620fe03b306dde0da012799d092e11c6377bd1a2c14e990b2
6
+ metadata.gz: 6fca5a15965145969a683b4f3466a067812ae6680a6a171e885854b6e8e1a684685cb0b37b6ffd52045c8404a95237ddfdd45628e39c0e33a779512ee5a56f5b
7
+ data.tar.gz: c32438302db80117e82bec0964c58177cca8579765e5169d127b423927430ab2cff2c51f8b6858e09ea53044b8cf6205524398d0a2e8560738499e9e80983dfa
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)
3
+ ### [master (unreleased)](https://github.com/rails-api/active_model_serializers/compare/v0.10.12...0-10-stable)
4
4
 
5
5
  Breaking changes:
6
6
 
@@ -10,6 +10,158 @@ Fixes:
10
10
 
11
11
  Misc:
12
12
 
13
+ ### [v0.10.12 (2020-12-10)](https://github.com/rails-api/active_model_serializers/compare/v0.10.11...v0.10.12)
14
+
15
+ Fixes:
16
+
17
+ - [#2398](https://github.com/rails-api/active_model_serializers/pull/2398) Update rails dependency to < 6.2 (@ritikesh)
18
+
19
+ ### [v0.10.11 (2020-12-04)](https://github.com/rails-api/active_model_serializers/compare/v0.10.10...v0.10.11)
20
+
21
+ Features:
22
+
23
+ - [#2361](https://github.com/rails-api/active_model_serializers/pull/2361) Add `ActiveModelSerializers.config.use_sha1_digests` to allow customization of the hashing algorithm used for serializer caching (@alexzherdev)
24
+
25
+ Fixes:
26
+
27
+ - [#2344](https://github.com/rails-api/active_model_serializers/pull/2344) Fixes #2341 introduced since #2223 (@wasifhossain)
28
+ - [#2395](https://github.com/rails-api/active_model_serializers/pull/2395) remove explicit require for thread_safe (@ritikesh)
29
+
30
+ ### [v0.10.10 (2019-07-13)](https://github.com/rails-api/active_model_serializers/compare/v0.10.9...v0.10.10)
31
+
32
+ Fixes:
33
+
34
+ - [#2319](https://github.com/rails-api/active_model_serializers/pull/2319) Fixes #2316. (@kylekeesling)
35
+ - Fix Rails 6.0 deprication warnings
36
+ - update test fixture schema to use `timestamps` instead of `timestamp`
37
+ - [#2223](https://github.com/rails-api/active_model_serializers/pull/2223) Support Fieldset in Attributes/JSON adapters documented in [docs/general/fields.md](https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/fields.md) that worked partially before (@bf4)
38
+ - [#2337](https://github.com/rails-api/active_model_serializers/pull/2337) fix incorrect belongs_to serialization when foreign_key on object and belongs_to is blank (@InteNs)
39
+ - Fixes incorrect json-api generation when `jsonapi_use_foreign_key_on_belongs_to_relationship` is `true` and the relationship is blank
40
+ - [#2172](https://github.com/rails-api/active_model_serializers/pull/2172) Preserve the namespace when falling back to a superclass serializer
41
+
42
+ Misc:
43
+
44
+ - [#2327](https://github.com/rails-api/active_model_serializers/pull/2327) Add support for Ruby 2.6 on Travis CI (@wasifhossain)
45
+ - [#2304](https://github.com/rails-api/active_model_serializers/pull/2304) Slim down bundled gem by excluding test files and docs (@greysteil)
46
+
47
+ ### [v0.10.9 (2019-02-08)](https://github.com/rails-api/active_model_serializers/compare/v0.10.8...v0.10.9)
48
+
49
+ Fixes:
50
+
51
+ - [#2288](https://github.com/rails-api/active_model_serializers/pull/2288)
52
+ Change the fetch method to deal with recyclable key cache strategy.
53
+ Fixes #2287. (@cintamani, @wasifhossain)
54
+ - [#2307](https://github.com/rails-api/active_model_serializers/pull/2307) Falsey attribute values should not be reevaluated.
55
+
56
+ Misc:
57
+
58
+ - [#2309](https://github.com/rails-api/active_model_serializers/pull/2309) Performance and memory usage fixes
59
+
60
+ ### [v0.10.8 (2018-11-01)](https://github.com/rails-api/active_model_serializers/compare/v0.10.7...v0.10.8)
61
+
62
+ Features:
63
+ - [#2279](https://github.com/rails-api/active_model_serializers/pull/2279) Support condition options in serializer link statements
64
+
65
+ Fixes:
66
+
67
+ - [#2296](https://github.com/rails-api/active_model_serializers/pull/2296) Fixes #2295 (@Hirurg103)
68
+ - Fix finding of namespaced serializer and non-namespaced model.
69
+ - [#2289](https://github.com/rails-api/active_model_serializers/pull/2289) Fixes #2255 (@f-mer)
70
+ - Fix autoloading race condition, especially in Rails 5.
71
+ - [#2299](https://github.com/rails-api/active_model_serializers/pull/2299) Fixes #2270 (@chau-bao-long via #2276)
72
+ - Fix reflection thread-safety bug
73
+
74
+ ### [v0.10.7 (2017-11-14)](https://github.com/rails-api/active_model_serializers/compare/v0.10.6...v0.10.7)
75
+
76
+ Regressions Fixed From v0.10.6:
77
+
78
+ - [#2211](https://github.com/rails-api/active_model_serializers/pull/2211). Fixes #2125, #2160. (@bf4)
79
+ - Fix polymorphic belongs_to tests; passes on v0.10.5, fails on v0.10.6
80
+ - Fix JSON:API polymorphic type regression from v0.10.5
81
+ - Fix JSON:API: for_type_and_id should always inflect_type
82
+ ```
83
+ Should Serializer._type ever be inflected?
84
+ Right now, it won't be, but association.serializer._type will be inflected.
85
+
86
+ That's the current behavior.
87
+ ```
88
+ - [#2216](https://github.com/rails-api/active_model_serializers/pull/2216). Fixes #2132, #2180. (@bf4)
89
+ - Fix JSON:API: Serialize resource type for unpersisted records (blank id)
90
+ - [#2218](https://github.com/rails-api/active_model_serializers/pull/2218). Fixes #2178. (@bf4)
91
+ - Fix JSON:API: Make using foreign key on belongs_to opt-in. No effect on polymorphic relationships.
92
+ ```
93
+ # set to true to opt-in
94
+ ActiveModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship = true
95
+ ```
96
+
97
+ Features:
98
+
99
+ - [#2136](https://github.com/rails-api/active_model_serializers/pull/2136) Enable inclusion of sideloaded relationship objects by `key`. (@caomania)
100
+ - [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. Originally in [#1982](https://github.com/rails-api/active_model_serializers/pull/1982). (@bf4)
101
+ - [#2130](https://github.com/rails-api/active_model_serializers/pull/2130) Allow serialized ID to be overwritten for belongs-to relationships. (@greysteil)
102
+ - [#2189](https://github.com/rails-api/active_model_serializers/pull/2189)
103
+ Update version constraint for jsonapi-renderer to `['>= 0.1.1.beta1', '< 0.3']`
104
+ (@tagliala)
105
+
106
+ Fixes:
107
+
108
+ - [#2022](https://github.com/rails-api/active_model_serializers/pull/2022) Mutation of ActiveModelSerializers::Model now changes the attributes. Originally in [#1984](https://github.com/rails-api/active_model_serializers/pull/1984). (@bf4)
109
+ - [#2200](https://github.com/rails-api/active_model_serializers/pull/2200) Fix deserialization of polymorphic relationships. (@dennis95stumm)
110
+ - [#2214](https://github.com/rails-api/active_model_serializers/pull/2214) Fail if unable to infer collection type with json adapter. (@jmeredith16)
111
+ - [#2149](https://github.com/rails-api/active_model_serializers/pull/2149) Always include self, first, last pagination link. (@mecampbellsoup)
112
+ - [#2179](https://github.com/rails-api/active_model_serializers/pull/2179) Fixes #2173, Pass block to Enumerator.new. (@drn)
113
+
114
+ Misc:
115
+
116
+ - [#2176](https://github.com/rails-api/active_model_serializers/pull/2176) Documentation for global adapter config. (@mrpinsky)
117
+ - [#2215](https://github.com/rails-api/active_model_serializers/pull/2215) Update `serializers.md` documentation to denote alternate use cases for `scope`. (@stratigos)
118
+ - [#2212](https://github.com/rails-api/active_model_serializers/pull/2212) Remove legacy has_many_embed_ids test. (@bf4)
119
+
120
+ ### [v0.10.6 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.10.5...v0.10.6)
121
+
122
+ Fixes:
123
+
124
+ - [#1857](https://github.com/rails-api/active_model_serializers/pull/1857) JSON:API does not load belongs_to relation to get identifier id. (@bf4)
125
+ - [#2119](https://github.com/rails-api/active_model_serializers/pull/2119) JSON:API returns null resource object identifier when 'id' is null. (@bf4)
126
+ - [#2093](https://github.com/rails-api/active_model_serializers/pull/2093) undef problematic Serializer methods: display, select. (@bf4)
127
+
128
+ Misc:
129
+
130
+ - [#2104](https://github.com/rails-api/active_model_serializers/pull/2104) Documentation for serializers and rendering. (@cassidycodes)
131
+ - [#2081](https://github.com/rails-api/active_model_serializers/pull/2081) Documentation for `include` option in adapters. (@charlie-wasp)
132
+ - [#2120](https://github.com/rails-api/active_model_serializers/pull/2120) Documentation for association options: foreign_key, type, class_name, namespace. (@bf4)
133
+
134
+ ### [v0.10.5 (2017-03-07)](https://github.com/rails-api/active_model_serializers/compare/v0.10.4...v0.10.5)
135
+
136
+ Breaking changes:
137
+
138
+ Features:
139
+
140
+ - [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. Originally in [#1982](https://github.com/rails-api/active_model_serializers/pull/1982). (@bf4)
141
+ - [#2057](https://github.com/rails-api/active_model_serializers/pull/2057)
142
+ Update version constraint for jsonapi-renderer to `['>= 0.1.1.beta1', '< 0.2']`
143
+ (@jaredbeck)
144
+
145
+ Fixes:
146
+
147
+ - [#2022](https://github.com/rails-api/active_model_serializers/pull/2022) Mutation of ActiveModelSerializers::Model now changes the attributes. Originally in [#1984](https://github.com/rails-api/active_model_serializers/pull/1984). (@bf4)
148
+
149
+ Misc:
150
+
151
+ - [#2055](https://github.com/rails-api/active_model_serializers/pull/2055)
152
+ Replace deprecated dependency jsonapi with jsonapi-renderer. (@jaredbeck)
153
+ - [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) Make test attributes explicit. Tests have Model#associations. (@bf4)
154
+ - [#1981](https://github.com/rails-api/active_model_serializers/pull/1981) Fix relationship link documentation. (@groyoh)
155
+ - [#2035](https://github.com/rails-api/active_model_serializers/pull/2035) Document how to disable the logger. (@MSathieu)
156
+ - [#2039](https://github.com/rails-api/active_model_serializers/pull/2039) Documentation fixes. (@biow0lf)
157
+
158
+ ### [v0.10.4 (2017-01-06)](https://github.com/rails-api/active_model_serializers/compare/v0.10.3...v0.10.4)
159
+
160
+ Misc:
161
+
162
+ - [#2005](https://github.com/rails-api/active_model_serializers/pull/2005) Update jsonapi runtime dependency to 0.1.1.beta6, support Ruby 2.4. (@kofronpi)
163
+ - [#1993](https://github.com/rails-api/active_model_serializers/pull/1993) Swap out KeyTransform for CaseTransform gem for the possibility of native extension use. (@NullVoxPopuli)
164
+
13
165
  ### [v0.10.3 (2016-11-21)](https://github.com/rails-api/active_model_serializers/compare/v0.10.2...v0.10.3)
14
166
 
15
167
  Fixes:
@@ -46,7 +198,7 @@ Misc:
46
198
 
47
199
  - [#1878](https://github.com/rails-api/active_model_serializers/pull/1878) Cache key generation for serializers now uses `ActiveSupport::Cache.expand_cache_key` instead of `Array#join` by default and is also overridable. This change should be backward-compatible. (@markiz)
48
200
 
49
- - [#1799](https://github.com/rails-api/active_model_serializers/pull/1799) Add documentation for setting the adapter. (@ScottKbka)
201
+ - [#1799](https://github.com/rails-api/active_model_serializers/pull/1799) Add documentation for setting the adapter. (@cassidycodes)
50
202
  - [#1909](https://github.com/rails-api/active_model_serializers/pull/1909) Add documentation for relationship links. (@vasilakisfil, @NullVoxPopuli)
51
203
  - [#1959](https://github.com/rails-api/active_model_serializers/pull/1959) Add documentation for root. (@shunsuke227ono)
52
204
  - [#1967](https://github.com/rails-api/active_model_serializers/pull/1967) Improve type method documentation. (@yukideluxe)
data/README.md CHANGED
@@ -4,8 +4,8 @@
4
4
  <tr>
5
5
  <td>Build Status</td>
6
6
  <td>
7
- <a href="https://travis-ci.org/rails-api/active_model_serializers"><img src="https://travis-ci.org/rails-api/active_model_serializers.svg?branch=master" alt="Build Status" ></a>
8
- <a href="https://ci.appveyor.com/project/joaomdmoura/active-model-serializers/branch/master"><img src="https://ci.appveyor.com/api/projects/status/x6xdjydutm54gvyt/branch/master?svg=true" alt="Build status"></a>
7
+ <a href="https://travis-ci.org/rails-api/active_model_serializers"><img src="https://api.travis-ci.org/rails-api/active_model_serializers.svg?branch=0-10-stable" alt="Build Status" ></a>
8
+ <a href="https://ci.appveyor.com/project/bf4/active-model-serializers/branch/0-10-stable"><img src="https://ci.appveyor.com/api/projects/status/x6xdjydutm54gvyt/branch/master?svg=true" alt="Build status"></a>
9
9
  </td>
10
10
  </tr>
11
11
  <tr>
@@ -41,7 +41,7 @@ these methods to the adapter.)
41
41
 
42
42
  By default ActiveModelSerializers will use the **Attributes Adapter** (no JSON root).
43
43
  But we strongly advise you to use **JsonApi Adapter**, which
44
- follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
44
+ follows 1.0 of the format specified in [jsonapi.org/format](https://jsonapi.org/format).
45
45
  Check how to change the adapter in the sections below.
46
46
 
47
47
  `0.10.x` is **not** backward compatible with `0.9.x` nor `0.8.x`.
@@ -49,8 +49,6 @@ Check how to change the adapter in the sections below.
49
49
  `0.10.x` is based on the `0.8.0` code, but with a more flexible
50
50
  architecture. We'd love your help. [Learn how you can help here.](CONTRIBUTING.md)
51
51
 
52
- It is generally safe and recommended to use the master branch.
53
-
54
52
  ## Installation
55
53
 
56
54
  Add this line to your application's Gemfile:
@@ -77,20 +75,26 @@ More information is available in the [Guides](docs) and
77
75
  If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new)
78
76
  and see our [contributing guide](CONTRIBUTING.md).
79
77
 
80
- If you have a question, please [post to Stack Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
78
+ If you have a question, please [post to Stack Overflow](https://stackoverflow.com/questions/tagged/active-model-serializers).
81
79
 
82
- If you'd like to chat, we have a [community slack](http://amserializers.herokuapp.com).
80
+ If you'd like to chat, we have a [community slack](https://amserializers.herokuapp.com).
83
81
 
84
82
  Thanks!
85
83
 
86
84
  ## Documentation
87
- - [0.10 (master) Documentation](https://github.com/rails-api/active_model_serializers/tree/master)
88
- - [![API Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/active_model_serializers/0.10.2)
89
- - [Guides](docs)
85
+
86
+ If you're reading this at https://github.com/rails-api/active_model_serializers you are
87
+ reading documentation for our `master`, which may include features that have not
88
+ been released yet. Please see below for the documentation relevant to you.
89
+
90
+ - [0.10 (0-10-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-10-stable)
91
+ - [0.10.10 (latest release) Documentation](https://github.com/rails-api/active_model_serializers/tree/v0.10.10)
92
+ - [![API Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/active_model_serializers/0.10.10)
93
+ - [Guides](docs)
90
94
  - [0.9 (0-9-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
91
- - [![API Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/rails-api/active_model_serializers/0-9-stable)
95
+ - [![API Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/active_model_serializers/0.9.7)
92
96
  - [0.8 (0-8-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
93
- - [![API Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/rails-api/active_model_serializers/0-8-stable)
97
+ - [![API Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/active_model_serializers/0.8.4)
94
98
 
95
99
 
96
100
  ## High-level behavior
@@ -110,7 +114,7 @@ class SomeResource < ActiveRecord::Base
110
114
  end
111
115
  # or
112
116
  class SomeResource < ActiveModelSerializers::Model
113
- attr_accessor :title, :body
117
+ attributes :title, :body
114
118
  end
115
119
  ```
116
120
 
@@ -156,11 +160,145 @@ serializer = SomeSerializer.new(resource, serializer_options)
156
160
  serializer.attributes
157
161
  serializer.associations
158
162
  ```
159
- See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for more information.
163
+
164
+ ## Architecture
165
+
166
+ This section focuses on architecture the 0.10.x version of ActiveModelSerializers. If you are interested in the architecture of the 0.8 or 0.9 versions,
167
+ please refer to the [0.8 README](https://github.com/rails-api/active_model_serializers/blob/0-8-stable/README.md) or
168
+ [0.9 README](https://github.com/rails-api/active_model_serializers/blob/0-9-stable/README.md).
169
+
170
+ The original design is also available [here](https://github.com/rails-api/active_model_serializers/blob/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e/README.textile).
171
+
172
+ ### ActiveModel::Serializer
173
+
174
+ An **`ActiveModel::Serializer`** wraps a [serializable resource](https://github.com/rails/rails/blob/master/activemodel/lib/active_model/serialization.rb)
175
+ and exposes an `attributes` method, among a few others.
176
+ It allows you to specify which attributes and associations should be represented in the serializatation of the resource.
177
+ It requires an adapter to transform its attributes into a JSON document; it cannot be serialized itself.
178
+ It may be useful to think of it as a
179
+ [presenter](https://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
180
+
181
+ #### ActiveModel::CollectionSerializer
182
+
183
+ The **`ActiveModel::CollectionSerializer`** represents a collection of resources as serializers
184
+ and, if there is no serializer, primitives.
185
+
186
+ ### ActiveModelSerializers::Adapter::Base
187
+
188
+ The **`ActiveModelSerializers::Adapter::Base`** describes the structure of the JSON document generated from a
189
+ serializer. For example, the `Attributes` example represents each serializer as its
190
+ unmodified attributes. The `JsonApi` adapter represents the serializer as a [JSON
191
+ API](https://jsonapi.org/) document.
192
+
193
+ ### ActiveModelSerializers::SerializableResource
194
+
195
+ The **`ActiveModelSerializers::SerializableResource`** acts to coordinate the serializer(s) and adapter
196
+ to an object that responds to `to_json`, and `as_json`. It is used in the controller to
197
+ encapsulate the serialization resource when rendered. However, it can also be used on its own
198
+ to serialize a resource outside of a controller, as well.
199
+
200
+ ### Primitive handling
201
+
202
+ Definitions: A primitive is usually a String or Array. There is no serializer
203
+ defined for them; they will be serialized when the resource is converted to JSON (`as_json` or
204
+ `to_json`). (The below also applies for any object with no serializer.)
205
+
206
+ - ActiveModelSerializers doesn't handle primitives passed to `render json:` at all.
207
+
208
+ Internally, if no serializer can be found in the controller, the resource is not decorated by
209
+ ActiveModelSerializers.
210
+
211
+ - However, when a primitive value is an attribute or in a collection, it is not modified.
212
+
213
+ When serializing a collection and the collection serializer (CollectionSerializer) cannot
214
+ identify a serializer for a resource in its collection, it throws [`:no_serializer`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128).
215
+ For example, when caught by `Reflection#build_association`, and the association value is set directly:
216
+
217
+ ```ruby
218
+ reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
219
+ ```
220
+
221
+ (which is called by the adapter as `serializer.associations(*)`.)
222
+
223
+ ### How options are parsed
224
+
225
+ High-level overview:
226
+
227
+ - For a **collection**
228
+ - `:serializer` specifies the collection serializer and
229
+ - `:each_serializer` specifies the serializer for each resource in the collection.
230
+ - For a **single resource**, the `:serializer` option is the resource serializer.
231
+ - Options are partitioned in serializer options and adapter options. Keys for adapter options are specified by
232
+ [`ADAPTER_OPTION_KEYS`](lib/active_model_serializers/serializable_resource.rb#L5).
233
+ The remaining options are serializer options.
234
+
235
+ Details:
236
+
237
+ 1. **ActionController::Serialization**
238
+ 1. `serializable_resource = ActiveModelSerializers::SerializableResource.new(resource, options)`
239
+ 1. `options` are partitioned into `adapter_opts` and everything else (`serializer_opts`).
240
+ The `adapter_opts` keys are defined in [`ActiveModelSerializers::SerializableResource::ADAPTER_OPTION_KEYS`](lib/active_model_serializers/serializable_resource.rb#L5).
241
+ 1. **ActiveModelSerializers::SerializableResource**
242
+ 1. `if serializable_resource.serializer?` (there is a serializer for the resource, and an adapter is used.)
243
+ - Where `serializer?` is `use_adapter? && !!(serializer)`
244
+ - Where `use_adapter?`: 'True when no explicit adapter given, or explicit value is truthy (non-nil);
245
+ False when explicit adapter is falsy (nil or false)'
246
+ - Where `serializer`:
247
+ 1. from explicit `:serializer` option, else
248
+ 2. implicitly from resource `ActiveModel::Serializer.serializer_for(resource)`
249
+ 1. A side-effect of checking `serializer` is:
250
+ - The `:serializer` option is removed from the serializer_opts hash
251
+ - If the `:each_serializer` option is present, it is removed from the serializer_opts hash and set as the `:serializer` option
252
+ 1. The serializer and adapter are created as
253
+ 1. `serializer_instance = serializer.new(resource, serializer_opts)`
254
+ 2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
255
+ 1. **ActiveModel::Serializer::CollectionSerializer#new**
256
+ 1. If the `serializer_instance` was a `CollectionSerializer` and the `:serializer` serializer_opts
257
+ is present, then [that serializer is passed into each resource](https://github.com/rails-api/active_model_serializers/blob/0-10-stable/lib/active_model/serializer/collection_serializer.rb#L77-L79).
258
+ 1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
259
+ resource as defined by the serializer.
260
+
261
+ (In Rails, the `options` are also passed to the `as_json(options)` or `to_json(options)`
262
+ methods on the resource serialization by the Rails JSON renderer. They are, therefore, important
263
+ to know about, but not part of ActiveModelSerializers.)
264
+
265
+ ### What does a 'serializable resource' look like?
266
+
267
+ - An `ActiveRecord::Base` object.
268
+ - Any Ruby object that passes the
269
+ [Lint](https://www.rubydoc.info/gems/active_model_serializers/ActiveModel/Serializer/Lint/Tests)
270
+ [(code)](lib/active_model/serializer/lint.rb).
271
+
272
+ ActiveModelSerializers provides a
273
+ [`ActiveModelSerializers::Model`](lib/active_model_serializers/model.rb),
274
+ which is a simple serializable PORO (Plain-Old Ruby Object).
275
+
276
+ `ActiveModelSerializers::Model` may be used either as a reference implementation, or in production code.
277
+
278
+ ```ruby
279
+ class MyModel < ActiveModelSerializers::Model
280
+ attributes :id, :name, :level
281
+ end
282
+ ```
283
+
284
+ The default serializer for `MyModel` would be `MyModelSerializer` whether MyModel is an
285
+ ActiveRecord::Base object or not.
286
+
287
+ Outside of the controller the rules are **exactly** the same as for records. For example:
288
+
289
+ ```ruby
290
+ render json: MyModel.new(level: 'awesome'), adapter: :json
291
+ ```
292
+
293
+ would be serialized the same as
294
+
295
+ ```ruby
296
+ ActiveModelSerializers::SerializableResource.new(MyModel.new(level: 'awesome'), adapter: :json).as_json
297
+ ```
160
298
 
161
299
  ## Semantic Versioning
162
300
 
163
- This project adheres to [semver](http://semver.org/)
301
+ This project adheres to [semver](https://semver.org/)
164
302
 
165
303
  ## Contributing
166
304
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/class/attribute'
2
4
  require 'active_model_serializers/serialization_context'
3
5
 
@@ -21,7 +23,15 @@ module ActionController
21
23
  end
22
24
 
23
25
  def namespace_for_serializer
24
- @namespace_for_serializer ||= self.class.parent unless self.class.parent == Object
26
+ @namespace_for_serializer ||= namespace_for_class(self.class) unless namespace_for_class(self.class) == Object
27
+ end
28
+
29
+ def namespace_for_class(klass)
30
+ if Module.method_defined?(:module_parent)
31
+ klass.module_parent
32
+ else
33
+ klass.parent
34
+ end
25
35
  end
26
36
 
27
37
  def serialization_scope
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module ActiveModel
@@ -1,16 +1,11 @@
1
- require 'thread_safe'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'jsonapi/include_directive'
3
4
  require 'active_model/serializer/collection_serializer'
4
5
  require 'active_model/serializer/array_serializer'
5
6
  require 'active_model/serializer/error_serializer'
6
7
  require 'active_model/serializer/errors_serializer'
7
- require 'active_model/serializer/concerns/associations'
8
- require 'active_model/serializer/concerns/attributes'
9
8
  require 'active_model/serializer/concerns/caching'
10
- require 'active_model/serializer/concerns/configuration'
11
- require 'active_model/serializer/concerns/links'
12
- require 'active_model/serializer/concerns/meta'
13
- require 'active_model/serializer/concerns/type'
14
9
  require 'active_model/serializer/fieldset'
15
10
  require 'active_model/serializer/lint'
16
11
 
@@ -18,33 +13,41 @@ require 'active_model/serializer/lint'
18
13
  # reified when subclassed to decorate a resource.
19
14
  module ActiveModel
20
15
  class Serializer
16
+ undef_method :select, :display # These IO methods, which are mixed into Kernel,
17
+ # sometimes conflict with attribute names. We don't need these IO methods.
18
+
21
19
  # @see #serializable_hash for more details on these valid keys.
22
20
  SERIALIZABLE_HASH_VALID_KEYS = [:only, :except, :methods, :include, :root].freeze
23
21
  extend ActiveSupport::Autoload
24
- autoload :Adapter
25
- autoload :Null
26
- include Configuration
27
- include Associations
28
- include Attributes
22
+ eager_autoload do
23
+ autoload :Adapter
24
+ autoload :Null
25
+ autoload :Attribute
26
+ autoload :Link
27
+ autoload :Association
28
+ autoload :Reflection
29
+ autoload :BelongsToReflection
30
+ autoload :HasOneReflection
31
+ autoload :HasManyReflection
32
+ end
33
+ include ActiveSupport::Configurable
29
34
  include Caching
30
- include Links
31
- include Meta
32
- include Type
33
35
 
34
36
  # @param resource [ActiveRecord::Base, ActiveModelSerializers::Model]
35
37
  # @return [ActiveModel::Serializer]
36
38
  # Preferentially returns
37
- # 1. resource.serializer
39
+ # 1. resource.serializer_class
38
40
  # 2. ArraySerializer when resource is a collection
39
41
  # 3. options[:serializer]
40
42
  # 4. lookup serializer when resource is a Class
41
- def self.serializer_for(resource, options = {})
42
- if resource.respond_to?(:serializer_class)
43
- resource.serializer_class
44
- elsif resource.respond_to?(:to_ary)
43
+ def self.serializer_for(resource_or_class, options = {})
44
+ if resource_or_class.respond_to?(:serializer_class)
45
+ resource_or_class.serializer_class
46
+ elsif resource_or_class.respond_to?(:to_ary)
45
47
  config.collection_serializer
46
48
  else
47
- options.fetch(:serializer) { get_serializer_for(resource.class, options[:namespace]) }
49
+ resource_class = resource_or_class.class == Class ? resource_or_class : resource_or_class.class
50
+ options.fetch(:serializer) { get_serializer_for(resource_class, options[:namespace]) }
48
51
  end
49
52
  end
50
53
 
@@ -69,7 +72,7 @@ module ActiveModel
69
72
  # Used to cache serializer name => serializer class
70
73
  # when looked up by Serializer.get_serializer_for.
71
74
  def self.serializers_cache
72
- @serializers_cache ||= ThreadSafe::Cache.new
75
+ @serializers_cache ||= Concurrent::Map.new
73
76
  end
74
77
 
75
78
  # @api private
@@ -90,7 +93,9 @@ module ActiveModel
90
93
  if serializer_class
91
94
  serializer_class
92
95
  elsif klass.superclass
93
- get_serializer_for(klass.superclass)
96
+ get_serializer_for(klass.superclass, namespace)
97
+ else
98
+ nil # No serializer found
94
99
  end
95
100
  end
96
101
  end
@@ -111,6 +116,199 @@ module ActiveModel
111
116
  @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
112
117
  end
113
118
 
119
+ # Preferred interface is ActiveModelSerializers.config
120
+ # BEGIN DEFAULT CONFIGURATION
121
+ config.collection_serializer = ActiveModel::Serializer::CollectionSerializer
122
+ config.serializer_lookup_enabled = true
123
+
124
+ # @deprecated Use {#config.collection_serializer=} instead of this. Is
125
+ # compatibility layer for ArraySerializer.
126
+ def config.array_serializer=(collection_serializer)
127
+ self.collection_serializer = collection_serializer
128
+ end
129
+
130
+ # @deprecated Use {#config.collection_serializer} instead of this. Is
131
+ # compatibility layer for ArraySerializer.
132
+ def config.array_serializer
133
+ collection_serializer
134
+ end
135
+
136
+ config.default_includes = '*'
137
+ config.adapter = :attributes
138
+ config.key_transform = nil
139
+ config.jsonapi_pagination_links_enabled = true
140
+ config.jsonapi_resource_type = :plural
141
+ config.jsonapi_namespace_separator = '-'.freeze
142
+ config.jsonapi_version = '1.0'
143
+ config.jsonapi_toplevel_meta = {}
144
+ # Make JSON API top-level jsonapi member opt-in
145
+ # ref: http://jsonapi.org/format/#document-top-level
146
+ config.jsonapi_include_toplevel_object = false
147
+ config.jsonapi_use_foreign_key_on_belongs_to_relationship = false
148
+ config.include_data_default = true
149
+
150
+ # For configuring how serializers are found.
151
+ # This should be an array of procs.
152
+ #
153
+ # The priority of the output is that the first item
154
+ # in the evaluated result array will take precedence
155
+ # over other possible serializer paths.
156
+ #
157
+ # i.e.: First match wins.
158
+ #
159
+ # @example output
160
+ # => [
161
+ # "CustomNamespace::ResourceSerializer",
162
+ # "ParentSerializer::ResourceSerializer",
163
+ # "ResourceNamespace::ResourceSerializer" ,
164
+ # "ResourceSerializer"]
165
+ #
166
+ # If CustomNamespace::ResourceSerializer exists, it will be used
167
+ # for serialization
168
+ config.serializer_lookup_chain = ActiveModelSerializers::LookupChain::DEFAULT.dup
169
+
170
+ config.schema_path = 'test/support/schemas'
171
+ # END DEFAULT CONFIGURATION
172
+
173
+ with_options instance_writer: false, instance_reader: false do |serializer|
174
+ serializer.class_attribute :_attributes_data # @api private
175
+ self._attributes_data ||= {}
176
+ end
177
+ with_options instance_writer: false, instance_reader: true do |serializer|
178
+ serializer.class_attribute :_reflections
179
+ self._reflections ||= {}
180
+ serializer.class_attribute :_links # @api private
181
+ self._links ||= {}
182
+ serializer.class_attribute :_meta # @api private
183
+ serializer.class_attribute :_type # @api private
184
+ end
185
+
186
+ def self.inherited(base)
187
+ super
188
+ base._attributes_data = _attributes_data.dup
189
+ base._reflections = _reflections.dup
190
+ base._links = _links.dup
191
+ end
192
+
193
+ # @return [Array<Symbol>] Key names of declared attributes
194
+ # @see Serializer::attribute
195
+ def self._attributes
196
+ _attributes_data.keys
197
+ end
198
+
199
+ # BEGIN SERIALIZER MACROS
200
+
201
+ # @example
202
+ # class AdminAuthorSerializer < ActiveModel::Serializer
203
+ # attributes :id, :name, :recent_edits
204
+ def self.attributes(*attrs)
205
+ attrs = attrs.first if attrs.first.class == Array
206
+
207
+ attrs.each do |attr|
208
+ attribute(attr)
209
+ end
210
+ end
211
+
212
+ # @example
213
+ # class AdminAuthorSerializer < ActiveModel::Serializer
214
+ # attributes :id, :recent_edits
215
+ # attribute :name, key: :title
216
+ #
217
+ # attribute :full_name do
218
+ # "#{object.first_name} #{object.last_name}"
219
+ # end
220
+ #
221
+ # def recent_edits
222
+ # object.edits.last(5)
223
+ # end
224
+ def self.attribute(attr, options = {}, &block)
225
+ key = options.fetch(:key, attr)
226
+ _attributes_data[key] = Attribute.new(attr, options, block)
227
+ end
228
+
229
+ # @param [Symbol] name of the association
230
+ # @param [Hash<Symbol => any>] options for the reflection
231
+ # @return [void]
232
+ #
233
+ # @example
234
+ # has_many :comments, serializer: CommentSummarySerializer
235
+ #
236
+ def self.has_many(name, options = {}, &block) # rubocop:disable Style/PredicateName
237
+ associate(HasManyReflection.new(name, options, block))
238
+ end
239
+
240
+ # @param [Symbol] name of the association
241
+ # @param [Hash<Symbol => any>] options for the reflection
242
+ # @return [void]
243
+ #
244
+ # @example
245
+ # belongs_to :author, serializer: AuthorSerializer
246
+ #
247
+ def self.belongs_to(name, options = {}, &block)
248
+ associate(BelongsToReflection.new(name, options, block))
249
+ end
250
+
251
+ # @param [Symbol] name of the association
252
+ # @param [Hash<Symbol => any>] options for the reflection
253
+ # @return [void]
254
+ #
255
+ # @example
256
+ # has_one :author, serializer: AuthorSerializer
257
+ #
258
+ def self.has_one(name, options = {}, &block) # rubocop:disable Style/PredicateName
259
+ associate(HasOneReflection.new(name, options, block))
260
+ end
261
+
262
+ # Add reflection and define {name} accessor.
263
+ # @param [ActiveModel::Serializer::Reflection] reflection
264
+ # @return [void]
265
+ #
266
+ # @api private
267
+ def self.associate(reflection)
268
+ key = reflection.options[:key] || reflection.name
269
+ self._reflections[key] = reflection
270
+ end
271
+ private_class_method :associate
272
+
273
+ # Define a link on a serializer.
274
+ # @example
275
+ # link(:self) { resource_url(object) }
276
+ # @example
277
+ # link(:self) { "http://example.com/resource/#{object.id}" }
278
+ # @example
279
+ # link :resource, "http://example.com/resource"
280
+ # @example
281
+ # link(:callback, if: :internal?), { "http://example.com/callback" }
282
+ #
283
+ def self.link(name, *args, &block)
284
+ options = args.extract_options!
285
+ # For compatibility with the use case of passing link directly as string argument
286
+ # without block, we are creating a wrapping block
287
+ _links[name] = Link.new(name, options, block || ->(_serializer) { args.first })
288
+ end
289
+
290
+ # Set the JSON API meta attribute of a serializer.
291
+ # @example
292
+ # class AdminAuthorSerializer < ActiveModel::Serializer
293
+ # meta { stuff: 'value' }
294
+ # @example
295
+ # meta do
296
+ # { comment_count: object.comments.count }
297
+ # end
298
+ def self.meta(value = nil, &block)
299
+ self._meta = block || value
300
+ end
301
+
302
+ # Set the JSON API type of a serializer.
303
+ # @example
304
+ # class AdminAuthorSerializer < ActiveModel::Serializer
305
+ # type 'authors'
306
+ def self.type(type)
307
+ self._type = type && type.to_s
308
+ end
309
+
310
+ # END SERIALIZER MACROS
311
+
114
312
  attr_accessor :object, :root, :scope
115
313
 
116
314
  # `scope_name` is set as :current_user by default in the controller.
@@ -131,60 +329,64 @@ module ActiveModel
131
329
  true
132
330
  end
133
331
 
332
+ # Return the +attributes+ of +object+ as presented
333
+ # by the serializer.
334
+ def attributes(requested_attrs = nil, reload = false)
335
+ @attributes = nil if reload
336
+ @attributes ||= self.class._attributes_data.each_with_object({}) do |(key, attr), hash|
337
+ next if attr.excluded?(self)
338
+ next unless requested_attrs.nil? || requested_attrs.include?(key)
339
+ hash[key] = attr.value(self)
340
+ end
341
+ end
342
+
343
+ # @param [JSONAPI::IncludeDirective] include_directive (defaults to the
344
+ # +default_include_directive+ config value when not provided)
345
+ # @return [Enumerator<Association>]
346
+ def associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil)
347
+ include_slice ||= include_directive
348
+ return Enumerator.new {} unless object
349
+
350
+ Enumerator.new do |y|
351
+ (self.instance_reflections ||= self.class._reflections.deep_dup).each do |key, reflection|
352
+ next if reflection.excluded?(self)
353
+ next unless include_directive.key?(key)
354
+
355
+ association = reflection.build_association(self, instance_options, include_slice)
356
+ y.yield association
357
+ end
358
+ end
359
+ end
360
+
134
361
  # @return [Hash] containing the attributes and first level
135
362
  # associations, similar to how ActiveModel::Serializers::JSON is used
136
363
  # in ActiveRecord::Base.
137
- #
138
- # TODO: Include <tt>ActiveModel::Serializers::JSON</tt>.
139
- # So that the below is true:
140
- # @param options [nil, Hash] The same valid options passed to `serializable_hash`
141
- # (:only, :except, :methods, and :include).
142
- #
143
- # See
144
- # https://github.com/rails/rails/blob/v5.0.0.beta2/activemodel/lib/active_model/serializers/json.rb#L17-L101
145
- # https://github.com/rails/rails/blob/v5.0.0.beta2/activemodel/lib/active_model/serialization.rb#L85-L123
146
- # https://github.com/rails/rails/blob/v5.0.0.beta2/activerecord/lib/active_record/serialization.rb#L11-L17
147
- # https://github.com/rails/rails/blob/v5.0.0.beta2/activesupport/lib/active_support/core_ext/object/json.rb#L147-L162
148
- #
149
- # @example
150
- # # The :only and :except options can be used to limit the attributes included, and work
151
- # # similar to the attributes method.
152
- # serializer.as_json(only: [:id, :name])
153
- # serializer.as_json(except: [:id, :created_at, :age])
154
- #
155
- # # To include the result of some method calls on the model use :methods:
156
- # serializer.as_json(methods: :permalink)
157
- #
158
- # # To include associations use :include:
159
- # serializer.as_json(include: :posts)
160
- # # Second level and higher order associations work as well:
161
- # serializer.as_json(include: { posts: { include: { comments: { only: :body } }, only: :title } })
162
364
  def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
163
365
  adapter_options ||= {}
164
366
  options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
165
- cached_attributes = adapter_options[:cached_attributes] ||= {}
166
- resource = fetch_attributes(options[:fields], cached_attributes, adapter_instance)
167
- relationships = resource_relationships(adapter_options, options, adapter_instance)
367
+ if (fieldset = adapter_options[:fieldset])
368
+ options[:fields] = fieldset.fields_for(json_key)
369
+ end
370
+ resource = attributes_hash(adapter_options, options, adapter_instance)
371
+ relationships = associations_hash(adapter_options, options, adapter_instance)
168
372
  resource.merge(relationships)
169
373
  end
170
374
  alias to_hash serializable_hash
171
375
  alias to_h serializable_hash
172
376
 
173
377
  # @see #serializable_hash
174
- # TODO: When moving attributes adapter logic here, @see #serializable_hash
175
- # So that the below is true:
176
- # @param options [nil, Hash] The same valid options passed to `as_json`
177
- # (:root, :only, :except, :methods, and :include).
178
- # The default for `root` is nil.
179
- # The default value for include_root is false. You can change it to true if the given
180
- # JSON string includes a single root node.
181
378
  def as_json(adapter_opts = nil)
182
379
  serializable_hash(adapter_opts)
183
380
  end
184
381
 
185
382
  # Used by adapter as resource root.
186
383
  def json_key
187
- root || _type || object.class.model_name.to_s.underscore
384
+ root || _type ||
385
+ begin
386
+ object.class.model_name.to_s.underscore
387
+ rescue ArgumentError
388
+ 'anonymous_object'
389
+ end
188
390
  end
189
391
 
190
392
  def read_attribute_for_serialization(attr)
@@ -196,36 +398,28 @@ module ActiveModel
196
398
  end
197
399
 
198
400
  # @api private
199
- def resource_relationships(adapter_options, options, adapter_instance)
200
- relationships = {}
201
- include_directive = options.fetch(:include_directive)
202
- associations(include_directive).each do |association|
203
- adapter_opts = adapter_options.merge(include_directive: include_directive[association.key])
204
- relationships[association.key] ||= relationship_value_for(association, adapter_opts, adapter_instance)
401
+ def attributes_hash(_adapter_options, options, adapter_instance)
402
+ if self.class.cache_enabled?
403
+ fetch_attributes(options[:fields], options[:cached_attributes] || {}, adapter_instance)
404
+ elsif self.class.fragment_cache_enabled?
405
+ fetch_attributes_fragment(adapter_instance, options[:cached_attributes] || {})
406
+ else
407
+ attributes(options[:fields], true)
205
408
  end
206
-
207
- relationships
208
409
  end
209
410
 
210
411
  # @api private
211
- def relationship_value_for(association, adapter_options, adapter_instance)
212
- return association.options[:virtual_value] if association.options[:virtual_value]
213
- association_serializer = association.serializer
214
- association_object = association_serializer && association_serializer.object
215
- return unless association_object
216
-
217
- relationship_value = association_serializer.serializable_hash(adapter_options, {}, adapter_instance)
218
-
219
- if association.options[:polymorphic] && relationship_value
220
- polymorphic_type = association_object.class.name.underscore
221
- relationship_value = { type: polymorphic_type, polymorphic_type.to_sym => relationship_value }
412
+ def associations_hash(adapter_options, options, adapter_instance)
413
+ include_directive = options.fetch(:include_directive)
414
+ include_slice = options[:include_slice]
415
+ associations(include_directive, include_slice).each_with_object({}) do |association, relationships|
416
+ adapter_opts = adapter_options.merge(include_directive: include_directive[association.key], adapter_instance: adapter_instance)
417
+ relationships[association.key] = association.serializable_hash(adapter_opts, adapter_instance)
222
418
  end
223
-
224
- relationship_value
225
419
  end
226
420
 
227
421
  protected
228
422
 
229
- attr_accessor :instance_options
423
+ attr_accessor :instance_options, :instance_reflections
230
424
  end
231
425
  end