active_model_serializers 0.8.3 → 0.10.0

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 (232) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +29 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  4. data/.gitignore +17 -0
  5. data/.rubocop.yml +104 -0
  6. data/.rubocop_todo.yml +167 -0
  7. data/.simplecov +110 -0
  8. data/.travis.yml +39 -24
  9. data/CHANGELOG.md +465 -6
  10. data/CONTRIBUTING.md +105 -0
  11. data/Gemfile +50 -1
  12. data/{MIT-LICENSE.txt → MIT-LICENSE} +3 -2
  13. data/README.md +102 -590
  14. data/Rakefile +93 -8
  15. data/active_model_serializers.gemspec +65 -23
  16. data/appveyor.yml +24 -0
  17. data/bin/bench +171 -0
  18. data/bin/bench_regression +316 -0
  19. data/bin/serve_benchmark +39 -0
  20. data/docs/ARCHITECTURE.md +126 -0
  21. data/docs/README.md +40 -0
  22. data/docs/STYLE.md +58 -0
  23. data/docs/general/adapters.md +245 -0
  24. data/docs/general/caching.md +52 -0
  25. data/docs/general/configuration_options.md +100 -0
  26. data/docs/general/deserialization.md +100 -0
  27. data/docs/general/getting_started.md +133 -0
  28. data/docs/general/instrumentation.md +40 -0
  29. data/docs/general/key_transforms.md +40 -0
  30. data/docs/general/logging.md +14 -0
  31. data/docs/general/rendering.md +255 -0
  32. data/docs/general/serializers.md +372 -0
  33. data/docs/how-open-source-maintained.jpg +0 -0
  34. data/docs/howto/add_pagination_links.md +139 -0
  35. data/docs/howto/add_root_key.md +51 -0
  36. data/docs/howto/outside_controller_use.md +58 -0
  37. data/docs/howto/passing_arbitrary_options.md +27 -0
  38. data/docs/howto/serialize_poro.md +32 -0
  39. data/docs/howto/test.md +152 -0
  40. data/docs/integrations/ember-and-json-api.md +112 -0
  41. data/docs/integrations/grape.md +19 -0
  42. data/docs/jsonapi/errors.md +56 -0
  43. data/docs/jsonapi/schema/schema.json +366 -0
  44. data/docs/jsonapi/schema.md +151 -0
  45. data/docs/rfcs/0000-namespace.md +106 -0
  46. data/docs/rfcs/template.md +15 -0
  47. data/lib/action_controller/serialization.rb +31 -36
  48. data/lib/active_model/serializable_resource.rb +11 -0
  49. data/lib/active_model/serializer/adapter/attributes.rb +15 -0
  50. data/lib/active_model/serializer/adapter/base.rb +16 -0
  51. data/lib/active_model/serializer/adapter/json.rb +15 -0
  52. data/lib/active_model/serializer/adapter/json_api.rb +15 -0
  53. data/lib/active_model/serializer/adapter/null.rb +15 -0
  54. data/lib/active_model/serializer/adapter.rb +24 -0
  55. data/lib/active_model/serializer/array_serializer.rb +9 -0
  56. data/lib/active_model/serializer/association.rb +19 -0
  57. data/lib/active_model/serializer/associations.rb +87 -220
  58. data/lib/active_model/serializer/attribute.rb +25 -0
  59. data/lib/active_model/serializer/attributes.rb +82 -0
  60. data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
  61. data/lib/active_model/serializer/caching.rb +333 -0
  62. data/lib/active_model/serializer/collection_reflection.rb +7 -0
  63. data/lib/active_model/serializer/collection_serializer.rb +64 -0
  64. data/lib/active_model/serializer/configuration.rb +35 -0
  65. data/lib/active_model/serializer/error_serializer.rb +10 -0
  66. data/lib/active_model/serializer/errors_serializer.rb +27 -0
  67. data/lib/active_model/serializer/field.rb +90 -0
  68. data/lib/active_model/serializer/fieldset.rb +31 -0
  69. data/lib/active_model/serializer/has_many_reflection.rb +10 -0
  70. data/lib/active_model/serializer/has_one_reflection.rb +10 -0
  71. data/lib/active_model/serializer/include_tree.rb +111 -0
  72. data/lib/active_model/serializer/links.rb +35 -0
  73. data/lib/active_model/serializer/lint.rb +146 -0
  74. data/lib/active_model/serializer/meta.rb +29 -0
  75. data/lib/active_model/serializer/null.rb +17 -0
  76. data/lib/active_model/serializer/reflection.rb +147 -0
  77. data/lib/active_model/serializer/singular_reflection.rb +7 -0
  78. data/lib/active_model/serializer/type.rb +25 -0
  79. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  80. data/lib/active_model/serializer.rb +158 -481
  81. data/lib/active_model_serializers/adapter/attributes.rb +76 -0
  82. data/lib/active_model_serializers/adapter/base.rb +83 -0
  83. data/lib/active_model_serializers/adapter/json.rb +21 -0
  84. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +213 -0
  85. data/lib/active_model_serializers/adapter/json_api/error.rb +96 -0
  86. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +49 -0
  87. data/lib/active_model_serializers/adapter/json_api/link.rb +83 -0
  88. data/lib/active_model_serializers/adapter/json_api/meta.rb +37 -0
  89. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +62 -0
  90. data/lib/active_model_serializers/adapter/json_api/relationship.rb +52 -0
  91. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +37 -0
  92. data/lib/active_model_serializers/adapter/json_api.rb +516 -0
  93. data/lib/active_model_serializers/adapter/null.rb +9 -0
  94. data/lib/active_model_serializers/adapter.rb +92 -0
  95. data/lib/active_model_serializers/callbacks.rb +55 -0
  96. data/lib/active_model_serializers/deprecate.rb +55 -0
  97. data/lib/active_model_serializers/deserialization.rb +13 -0
  98. data/lib/active_model_serializers/json_pointer.rb +14 -0
  99. data/lib/active_model_serializers/key_transform.rb +70 -0
  100. data/lib/active_model_serializers/logging.rb +122 -0
  101. data/lib/active_model_serializers/model.rb +49 -0
  102. data/lib/active_model_serializers/railtie.rb +46 -0
  103. data/lib/active_model_serializers/register_jsonapi_renderer.rb +65 -0
  104. data/lib/active_model_serializers/serializable_resource.rb +81 -0
  105. data/lib/active_model_serializers/serialization_context.rb +32 -0
  106. data/lib/active_model_serializers/test/schema.rb +138 -0
  107. data/lib/active_model_serializers/test/serializer.rb +125 -0
  108. data/lib/active_model_serializers/test.rb +7 -0
  109. data/lib/active_model_serializers.rb +32 -89
  110. data/lib/generators/rails/USAGE +6 -0
  111. data/lib/generators/rails/resource_override.rb +10 -0
  112. data/lib/generators/rails/serializer_generator.rb +36 -0
  113. data/lib/generators/rails/templates/serializer.rb.erb +8 -0
  114. data/lib/grape/active_model_serializers.rb +14 -0
  115. data/lib/grape/formatters/active_model_serializers.rb +15 -0
  116. data/lib/grape/helpers/active_model_serializers.rb +16 -0
  117. data/test/action_controller/adapter_selector_test.rb +53 -0
  118. data/test/action_controller/explicit_serializer_test.rb +134 -0
  119. data/test/action_controller/json/include_test.rb +167 -0
  120. data/test/action_controller/json_api/deserialization_test.rb +112 -0
  121. data/test/action_controller/json_api/errors_test.rb +41 -0
  122. data/test/action_controller/json_api/linked_test.rb +197 -0
  123. data/test/action_controller/json_api/pagination_test.rb +116 -0
  124. data/test/action_controller/json_api/transform_test.rb +181 -0
  125. data/test/action_controller/serialization_scope_name_test.rb +229 -0
  126. data/test/action_controller/serialization_test.rb +469 -0
  127. data/test/active_model_serializers/adapter_for_test.rb +208 -0
  128. data/test/active_model_serializers/json_pointer_test.rb +20 -0
  129. data/test/active_model_serializers/key_transform_test.rb +263 -0
  130. data/test/active_model_serializers/logging_test.rb +77 -0
  131. data/test/active_model_serializers/model_test.rb +9 -0
  132. data/test/active_model_serializers/railtie_test_isolated.rb +63 -0
  133. data/test/active_model_serializers/serialization_context_test_isolated.rb +58 -0
  134. data/test/active_model_serializers/test/schema_test.rb +130 -0
  135. data/test/active_model_serializers/test/serializer_test.rb +62 -0
  136. data/test/active_record_test.rb +9 -0
  137. data/test/adapter/deprecation_test.rb +100 -0
  138. data/test/adapter/json/belongs_to_test.rb +45 -0
  139. data/test/adapter/json/collection_test.rb +90 -0
  140. data/test/adapter/json/has_many_test.rb +45 -0
  141. data/test/adapter/json/transform_test.rb +93 -0
  142. data/test/adapter/json_api/belongs_to_test.rb +155 -0
  143. data/test/adapter/json_api/collection_test.rb +95 -0
  144. data/test/adapter/json_api/errors_test.rb +78 -0
  145. data/test/adapter/json_api/fields_test.rb +87 -0
  146. data/test/adapter/json_api/has_many_embed_ids_test.rb +43 -0
  147. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +96 -0
  148. data/test/adapter/json_api/has_many_test.rb +144 -0
  149. data/test/adapter/json_api/has_one_test.rb +80 -0
  150. data/test/adapter/json_api/json_api_test.rb +35 -0
  151. data/test/adapter/json_api/linked_test.rb +392 -0
  152. data/test/adapter/json_api/links_test.rb +93 -0
  153. data/test/adapter/json_api/pagination_links_test.rb +166 -0
  154. data/test/adapter/json_api/parse_test.rb +137 -0
  155. data/test/adapter/json_api/relationship_test.rb +161 -0
  156. data/test/adapter/json_api/relationships_test.rb +199 -0
  157. data/test/adapter/json_api/resource_identifier_test.rb +85 -0
  158. data/test/adapter/json_api/resource_meta_test.rb +100 -0
  159. data/test/adapter/json_api/toplevel_jsonapi_test.rb +82 -0
  160. data/test/adapter/json_api/transform_test.rb +502 -0
  161. data/test/adapter/json_api/type_test.rb +61 -0
  162. data/test/adapter/json_test.rb +45 -0
  163. data/test/adapter/null_test.rb +23 -0
  164. data/test/adapter/polymorphic_test.rb +171 -0
  165. data/test/adapter_test.rb +67 -0
  166. data/test/array_serializer_test.rb +20 -73
  167. data/test/benchmark/app.rb +65 -0
  168. data/test/benchmark/benchmarking_support.rb +67 -0
  169. data/test/benchmark/bm_caching.rb +119 -0
  170. data/test/benchmark/bm_transform.rb +34 -0
  171. data/test/benchmark/config.ru +3 -0
  172. data/test/benchmark/controllers.rb +84 -0
  173. data/test/benchmark/fixtures.rb +219 -0
  174. data/test/cache_test.rb +485 -0
  175. data/test/collection_serializer_test.rb +110 -0
  176. data/test/fixtures/active_record.rb +78 -0
  177. data/test/fixtures/poro.rb +282 -0
  178. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  179. data/test/generators/serializer_generator_test.rb +57 -0
  180. data/test/grape_test.rb +82 -0
  181. data/test/include_tree/from_include_args_test.rb +26 -0
  182. data/test/include_tree/from_string_test.rb +94 -0
  183. data/test/include_tree/include_args_to_hash_test.rb +64 -0
  184. data/test/lint_test.rb +49 -0
  185. data/test/logger_test.rb +18 -0
  186. data/test/poro_test.rb +9 -0
  187. data/test/serializable_resource_test.rb +83 -0
  188. data/test/serializers/association_macros_test.rb +36 -0
  189. data/test/serializers/associations_test.rb +295 -0
  190. data/test/serializers/attribute_test.rb +151 -0
  191. data/test/serializers/attributes_test.rb +52 -0
  192. data/test/serializers/caching_configuration_test_isolated.rb +170 -0
  193. data/test/serializers/configuration_test.rb +32 -0
  194. data/test/serializers/fieldset_test.rb +14 -0
  195. data/test/serializers/meta_test.rb +196 -0
  196. data/test/serializers/options_test.rb +21 -0
  197. data/test/serializers/read_attribute_for_serialization_test.rb +79 -0
  198. data/test/serializers/root_test.rb +21 -0
  199. data/test/serializers/serialization_test.rb +55 -0
  200. data/test/serializers/serializer_for_test.rb +134 -0
  201. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  202. data/test/support/isolated_unit.rb +79 -0
  203. data/test/support/rails5_shims.rb +47 -0
  204. data/test/support/rails_app.rb +45 -0
  205. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  206. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
  207. data/test/support/schemas/custom/show.json +7 -0
  208. data/test/support/schemas/hyper_schema.json +93 -0
  209. data/test/support/schemas/render_using_json_api.json +43 -0
  210. data/test/support/schemas/simple_json_pointers.json +10 -0
  211. data/test/support/serialization_testing.rb +53 -0
  212. data/test/test_helper.rb +48 -23
  213. metadata +449 -43
  214. data/DESIGN.textile +0 -586
  215. data/Gemfile.edge +0 -9
  216. data/bench/perf.rb +0 -43
  217. data/cruft.md +0 -19
  218. data/lib/active_model/array_serializer.rb +0 -104
  219. data/lib/active_record/serializer_override.rb +0 -16
  220. data/lib/generators/resource_override.rb +0 -13
  221. data/lib/generators/serializer/USAGE +0 -9
  222. data/lib/generators/serializer/serializer_generator.rb +0 -42
  223. data/lib/generators/serializer/templates/serializer.rb +0 -19
  224. data/test/association_test.rb +0 -592
  225. data/test/caching_test.rb +0 -96
  226. data/test/generators_test.rb +0 -85
  227. data/test/no_serialization_scope_test.rb +0 -34
  228. data/test/serialization_scope_name_test.rb +0 -67
  229. data/test/serialization_test.rb +0 -392
  230. data/test/serializer_support_test.rb +0 -51
  231. data/test/serializer_test.rb +0 -1465
  232. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,245 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Adapters
4
+
5
+ ActiveModelSerializers offers the ability to configure which adapter
6
+ to use both globally and/or when serializing (usually when rendering).
7
+
8
+ The global adapter configuration is set on [`ActiveModelSerializers.config`](configuration_options.md).
9
+ It should be set only once, preferably at initialization.
10
+
11
+ For example:
12
+
13
+ ```ruby
14
+ ActiveModelSerializers.config.adapter = ActiveModelSerializers::Adapter::JsonApi
15
+ ```
16
+
17
+ or
18
+
19
+ ```ruby
20
+ ActiveModelSerializers.config.adapter = :json_api
21
+ ```
22
+
23
+ or
24
+
25
+ ```ruby
26
+ ActiveModelSerializers.config.adapter = :json
27
+ ```
28
+
29
+ The local adapter option is in the format `adapter: adapter`, where `adapter` is
30
+ any of the same values as set globally.
31
+
32
+ The configured adapter can be set as a symbol, class, or class name, as described in
33
+ [Advanced adapter configuration](adapters.md#advanced-adapter-configuration).
34
+
35
+ The `Attributes` adapter does not include a root key. It is just the serialized attributes.
36
+
37
+ Use either the `JSON` or `JSON API` adapters if you want the response document to have a root key.
38
+
39
+ ## Built in Adapters
40
+
41
+ ### Attributes - Default
42
+
43
+ It's the default adapter, it generates a json response without a root key.
44
+ Doesn't follow any specific convention.
45
+
46
+ ##### Example output
47
+
48
+ ```json
49
+ {
50
+ "title": "Title 1",
51
+ "body": "Body 1",
52
+ "publish_at": "2020-03-16T03:55:25.291Z",
53
+ "author": {
54
+ "first_name": "Bob",
55
+ "last_name": "Jones"
56
+ },
57
+ "comments": [
58
+ {
59
+ "body": "cool"
60
+ },
61
+ {
62
+ "body": "awesome"
63
+ }
64
+ ]
65
+ }
66
+ ```
67
+
68
+ ### JSON
69
+
70
+ The response document always with a root key.
71
+
72
+ The root key **can't be overridden**, and will be derived from the resource being serialized.
73
+
74
+ Doesn't follow any specific convention.
75
+
76
+ ##### Example output
77
+
78
+ ```json
79
+ {
80
+ "post": {
81
+ "title": "Title 1",
82
+ "body": "Body 1",
83
+ "publish_at": "2020-03-16T03:55:25.291Z",
84
+ "author": {
85
+ "first_name": "Bob",
86
+ "last_name": "Jones"
87
+ },
88
+ "comments": [{
89
+ "body": "cool"
90
+ }, {
91
+ "body": "awesome"
92
+ }]
93
+ }
94
+ }
95
+ ```
96
+
97
+ ### JSON API
98
+
99
+ This adapter follows **version 1.0** of the [format specified](../jsonapi/schema.md) in
100
+ [jsonapi.org/format](http://jsonapi.org/format).
101
+
102
+ ##### Example output
103
+
104
+ ```json
105
+ {
106
+ "data": {
107
+ "id": "1337",
108
+ "type": "posts",
109
+ "attributes": {
110
+ "title": "Title 1",
111
+ "body": "Body 1",
112
+ "publish-at": "2020-03-16T03:55:25.291Z"
113
+ },
114
+ "relationships": {
115
+ "author": {
116
+ "data": {
117
+ "id": "1",
118
+ "type": "authors"
119
+ }
120
+ },
121
+ "comments": {
122
+ "data": [{
123
+ "id": "7",
124
+ "type": "comments"
125
+ }, {
126
+ "id": "12",
127
+ "type": "comments"
128
+ }]
129
+ }
130
+ },
131
+ "links": {
132
+ "post-authors": "https://example.com/post_authors"
133
+ },
134
+ "meta": {
135
+ "rating": 5,
136
+ "favorite-count": 10
137
+ }
138
+ }
139
+ }
140
+ ```
141
+
142
+ #### Included
143
+
144
+ It will include the associated resources in the `"included"` member
145
+ when the resource names are included in the `include` option.
146
+ Including nested associated resources is also supported.
147
+
148
+ ```ruby
149
+ render json: @posts, include: ['author', 'comments', 'comments.author']
150
+ # or
151
+ render json: @posts, include: 'author,comments,comments.author'
152
+ ```
153
+
154
+ In addition, two types of wildcards may be used:
155
+
156
+ - `*` includes one level of associations.
157
+ - `**` includes all recursively.
158
+
159
+ These can be combined with other paths.
160
+
161
+ ```ruby
162
+ render json: @posts, include: '**' # or '*' for a single layer
163
+ ```
164
+
165
+ The format of the `include` option can be either:
166
+
167
+ - a String composed of a comma-separated list of [relationship paths](http://jsonapi.org/format/#fetching-includes).
168
+ - an Array of Symbols and Hashes.
169
+ - a mix of both.
170
+
171
+ The following would render posts and include:
172
+
173
+ - the author
174
+ - the author's comments, and
175
+ - every resource referenced by the author's comments (recursively).
176
+
177
+ It could be combined, like above, with other paths in any combination desired.
178
+
179
+ ```ruby
180
+ render json: @posts, include: 'author.comments.**'
181
+ ```
182
+
183
+ ##### Security Considerations
184
+
185
+ Since the included options may come from the query params (i.e. user-controller):
186
+
187
+ ```ruby
188
+ render json: @posts, include: params[:include]
189
+ ```
190
+
191
+ The user could pass in `include=**`.
192
+
193
+ We recommend filtering any user-supplied includes appropriately.
194
+
195
+ ## Advanced adapter configuration
196
+
197
+ ### Registering an adapter
198
+
199
+ The default adapter can be configured, as above, to use any class given to it.
200
+
201
+ An adapter may also be specified, e.g. when rendering, as a class or as a symbol.
202
+ If a symbol, then the adapter must be, e.g. `:great_example`,
203
+ `ActiveModelSerializers::Adapter::GreatExample`, or registered.
204
+
205
+ There are two ways to register an adapter:
206
+
207
+ 1) The simplest, is to subclass `ActiveModelSerializers::Adapter::Base`, e.g. the below will
208
+ register the `Example::UsefulAdapter` as `"example/useful_adapter"`.
209
+
210
+ ```ruby
211
+ module Example
212
+ class UsefulAdapter < ActiveModelSerializers::Adapter::Base
213
+ end
214
+ end
215
+ ```
216
+
217
+ You'll notice that the name it registers is the underscored namespace and class.
218
+
219
+ Under the covers, when the `ActiveModelSerializers::Adapter::Base` is subclassed, it registers
220
+ the subclass as `register("example/useful_adapter", Example::UsefulAdapter)`
221
+
222
+ 2) Any class can be registered as an adapter by calling `register` directly on the
223
+ `ActiveModelSerializers::Adapter` class. e.g., the below registers `MyAdapter` as
224
+ `:special_adapter`.
225
+
226
+ ```ruby
227
+ class MyAdapter; end
228
+ ActiveModelSerializers::Adapter.register(:special_adapter, MyAdapter)
229
+ ```
230
+
231
+ ### Looking up an adapter
232
+
233
+ | Method | Return value |
234
+ | :------------ |:---------------|
235
+ | `ActiveModelSerializers::Adapter.adapter_map` | A Hash of all known adapters `{ adapter_name => adapter_class }` |
236
+ | `ActiveModelSerializers::Adapter.adapters` | A (sorted) Array of all known `adapter_names` |
237
+ | `ActiveModelSerializers::Adapter.lookup(name_or_klass)` | The `adapter_class`, else raises an `ActiveModelSerializers::Adapter::UnknownAdapter` error |
238
+ | `ActiveModelSerializers::Adapter.adapter_class(adapter)` | Delegates to `ActiveModelSerializers::Adapter.lookup(adapter)` |
239
+ | `ActiveModelSerializers::Adapter.configured_adapter` | A convenience method for `ActiveModelSerializers::Adapter.lookup(config.adapter)` |
240
+
241
+ The registered adapter name is always a String, but may be looked up as a Symbol or String.
242
+ Helpfully, the Symbol or String is underscored, so that `get(:my_adapter)` and `get("MyAdapter")`
243
+ may both be used.
244
+
245
+ For more information, see [the Adapter class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/adapter.rb)
@@ -0,0 +1,52 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Caching
4
+
5
+ To cache a serializer, call ```cache``` and pass its options.
6
+ The options are the same options of ```ActiveSupport::Cache::Store```, plus
7
+ a ```key``` option that will be the prefix of the object cache
8
+ on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
9
+
10
+ The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
11
+
12
+ **[NOTE] Every object is individually cached.**
13
+
14
+ **[NOTE] The cache is automatically expired after an object is updated, but it's not deleted.**
15
+
16
+ ```ruby
17
+ cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
18
+ ```
19
+
20
+ Take the example bellow:
21
+
22
+ ```ruby
23
+ class PostSerializer < ActiveModel::Serializer
24
+ cache key: 'post', expires_in: 3.hours
25
+ attributes :title, :body
26
+
27
+ has_many :comments
28
+ end
29
+ ```
30
+
31
+ On this example every ```Post``` object will be cached with
32
+ the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
33
+ but in this case it will be automatically expired after 3 hours.
34
+
35
+ ## Fragment Caching
36
+
37
+ If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
38
+
39
+ You can define the attribute by using ```only``` or ```except``` option on cache method.
40
+
41
+ **[NOTE] Cache serializers will be used at their relationships**
42
+
43
+ Example:
44
+
45
+ ```ruby
46
+ class PostSerializer < ActiveModel::Serializer
47
+ cache key: 'post', expires_in: 3.hours, only: [:title]
48
+ attributes :title, :body
49
+
50
+ has_many :comments
51
+ end
52
+ ```
@@ -0,0 +1,100 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Configuration Options
4
+
5
+ The following configuration options can be set on
6
+ `ActiveModelSerializers.config`, preferably inside an initializer.
7
+
8
+ ## General
9
+
10
+ ##### adapter
11
+
12
+ The [adapter](adapters.md) to use.
13
+
14
+ Possible values:
15
+
16
+ - `:attributes` (default)
17
+ - `:json`
18
+ - `:json_api`
19
+
20
+ ##### serializer_lookup_enabled
21
+
22
+ Enable automatic serializer lookup.
23
+
24
+ Possible values:
25
+
26
+ - `true` (default)
27
+ - `false`
28
+
29
+ When `false`, serializers must be explicitly specified.
30
+
31
+ ##### key_transform
32
+
33
+ The [key transform](key_transforms.md) to use.
34
+
35
+
36
+ | Option | Result |
37
+ |----|----|
38
+ | `:camel` | ExampleKey |
39
+ | `:camel_lower` | exampleKey |
40
+ | `:dash` | example-key |
41
+ | `:unaltered` | the original, unaltered key |
42
+ | `:underscore` | example_key |
43
+ | `nil` | use the adapter default |
44
+
45
+ Each adapter has a default key transform configured:
46
+
47
+ | Adapter | Default Key Transform |
48
+ |----|----|
49
+ | `Json` | `:unaltered` |
50
+ | `JsonApi` | `:dash` |
51
+
52
+ `config.key_transform` is a global override of the adapter default. Adapters
53
+ still prefer the render option `:key_transform` over this setting.
54
+
55
+
56
+ ## JSON API
57
+
58
+
59
+ ##### jsonapi_resource_type
60
+
61
+ Sets whether the [type](http://jsonapi.org/format/#document-resource-identifier-objects)
62
+ of the resource should be `singularized` or `pluralized` when it is not
63
+ [explicitly specified by the serializer](https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#type)
64
+
65
+ Possible values:
66
+
67
+ - `:singular`
68
+ - `:plural` (default)
69
+
70
+ ##### jsonapi_include_toplevel_object
71
+
72
+ Include a [top level jsonapi member](http://jsonapi.org/format/#document-jsonapi-object)
73
+ in the response document.
74
+
75
+ Possible values:
76
+
77
+ - `true`
78
+ - `false` (default)
79
+
80
+ ##### jsonapi_version
81
+
82
+ The latest version of the spec to which the API conforms.
83
+
84
+ Default: `'1.0'`.
85
+
86
+ *Used when `jsonapi_include_toplevel_object` is `true`*
87
+
88
+ ##### jsonapi_toplevel_meta
89
+
90
+ Optional top-level metadata. Not included if empty.
91
+
92
+ Default: `{}`.
93
+
94
+ *Used when `jsonapi_include_toplevel_object` is `true`*
95
+
96
+
97
+ ## Hooks
98
+
99
+ To run a hook when ActiveModelSerializers is loaded, use
100
+ `ActiveSupport.on_load(:action_controller) do end`
@@ -0,0 +1,100 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Deserialization
4
+
5
+ This is currently an *experimental* feature. The interface may change.
6
+
7
+ ## JSON API
8
+
9
+ The `ActiveModelSerializers::Deserialization` defines two methods (namely `jsonapi_parse` and `jsonapi_parse!`), which take a `Hash` or an instance of `ActionController::Parameters` representing a JSON API payload, and return a hash that can directly be used to create/update models. The bang version throws an `InvalidDocument` exception when parsing fails, whereas the "safe" version simply returns an empty hash.
10
+
11
+ - Parameters
12
+ - document: `Hash` or `ActionController::Parameters` instance
13
+ - options:
14
+ - only: `Array` of whitelisted fields
15
+ - except: `Array` of blacklisted fields
16
+ - keys: `Hash` of fields the name of which needs to be modified (e.g. `{ :author => :user, :date => :created_at }`)
17
+
18
+ Examples:
19
+
20
+ ```ruby
21
+ class PostsController < ActionController::Base
22
+ def create
23
+ Post.create(create_params)
24
+ end
25
+
26
+ def create_params
27
+ ActiveModelSerializers::Deserialization.jsonapi_parse(params, only: [:title, :content, :author])
28
+ end
29
+ end
30
+ ```
31
+
32
+
33
+
34
+ Given a JSON API document,
35
+
36
+ ```
37
+ document = {
38
+ 'data' => {
39
+ 'id' => 1,
40
+ 'type' => 'post',
41
+ 'attributes' => {
42
+ 'title' => 'Title 1',
43
+ 'date' => '2015-12-20'
44
+ },
45
+ 'associations' => {
46
+ 'author' => {
47
+ 'data' => {
48
+ 'type' => 'user',
49
+ 'id' => '2'
50
+ }
51
+ },
52
+ 'second_author' => {
53
+ 'data' => nil
54
+ },
55
+ 'comments' => {
56
+ 'data' => [{
57
+ 'type' => 'comment',
58
+ 'id' => '3'
59
+ },{
60
+ 'type' => 'comment',
61
+ 'id' => '4'
62
+ }]
63
+ }
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ The entire document can be parsed without specifying any options:
70
+ ```ruby
71
+ ActiveModelSerializers::Deserialization.jsonapi_parse(document)
72
+ #=>
73
+ # {
74
+ # title: 'Title 1',
75
+ # date: '2015-12-20',
76
+ # author_id: 2,
77
+ # second_author_id: nil
78
+ # comment_ids: [3, 4]
79
+ # }
80
+ ```
81
+
82
+ and fields, relationships, and polymorphic relationships can be specified via the options:
83
+
84
+ ```ruby
85
+ ActiveModelSerializers::Deserialization
86
+ .jsonapi_parse(document, only: [:title, :date, :author],
87
+ keys: { date: :published_at },
88
+ polymorphic: [:author])
89
+ #=>
90
+ # {
91
+ # title: 'Title 1',
92
+ # published_at: '2015-12-20',
93
+ # author_id: '2',
94
+ # author_type: 'user'
95
+ # }
96
+ ```
97
+
98
+ ## Attributes/Json
99
+
100
+ There is currently no deserialization for those adapters.
@@ -0,0 +1,133 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Getting Started
4
+
5
+ ## Creating a Serializer
6
+
7
+ The easiest way to create a new serializer is to generate a new resource, which
8
+ will generate a serializer at the same time:
9
+
10
+ ```
11
+ $ rails g resource post title:string body:string
12
+ ```
13
+
14
+ This will generate a serializer in `app/serializers/post_serializer.rb` for
15
+ your new model. You can also generate a serializer for an existing model with
16
+ the serializer generator:
17
+
18
+ ```
19
+ $ rails g serializer post
20
+ ```
21
+
22
+ The generated serializer will contain basic `attributes` and
23
+ `has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
24
+
25
+ ```ruby
26
+ class PostSerializer < ActiveModel::Serializer
27
+ attributes :title, :body
28
+
29
+ has_many :comments
30
+ has_one :author
31
+ end
32
+ ```
33
+
34
+ and
35
+
36
+ ```ruby
37
+ class CommentSerializer < ActiveModel::Serializer
38
+ attributes :name, :body
39
+
40
+ belongs_to :post_id
41
+ end
42
+ ```
43
+
44
+ The attribute names are a **whitelist** of attributes to be serialized.
45
+
46
+ The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
47
+ resources. By default, when you serialize a `Post`, you will get its `Comments`
48
+ as well.
49
+
50
+ For more information, see [Serializers](/docs/general/serializers.md).
51
+
52
+ ### Namespaced Models
53
+
54
+ When serializing a model inside a namespace, such as `Api::V1::Post`, ActiveModelSerializers will expect the corresponding serializer to be inside the same namespace (namely `Api::V1::PostSerializer`).
55
+
56
+ ### Model Associations and Nested Serializers
57
+
58
+ When declaring a serializer for a model with associations, such as:
59
+ ```ruby
60
+ class PostSerializer < ActiveModel::Serializer
61
+ has_many :comments
62
+ end
63
+ ```
64
+ ActiveModelSerializers will look for `PostSerializer::CommentSerializer` in priority, and fall back to `::CommentSerializer` in case the former does not exist. This allows for more control over the way a model gets serialized as an association of an other model.
65
+
66
+ For example, in the following situation:
67
+
68
+ ```ruby
69
+ class CommentSerializer < ActiveModel::Serializer
70
+ attributes :body, :date, :nb_likes
71
+ end
72
+
73
+ class PostSerializer < ActiveModel::Serializer
74
+ has_many :comments
75
+ class CommentSerializer < ActiveModel::Serializer
76
+ attributes :body_short
77
+ end
78
+ end
79
+ ```
80
+
81
+ ActiveModelSerializers will use `PostSerializer::CommentSerializer` (thus including only the `:body_short` attribute) when serializing a `Comment` as part of a `Post`, but use `::CommentSerializer` when serializing a `Comment` directly (thus including `:body, :date, :nb_likes`).
82
+
83
+ ### Extending a Base `ApplicationSerializer`
84
+
85
+ By default, new serializers descend from `ActiveModel::Serializer`. However, if
86
+ you wish to share behavior across your serializers, you can create an
87
+ `ApplicationSerializer` at `app/serializers/application_serializer.rb`:
88
+
89
+ ```ruby
90
+ class ApplicationSerializer < ActiveModel::Serializer
91
+ end
92
+ ```
93
+
94
+ Then any newly-generated serializers will automatically descend from
95
+ `ApplicationSerializer`.
96
+
97
+ ```
98
+ $ rails g serializer post
99
+ ```
100
+
101
+ Now generates:
102
+
103
+ ```ruby
104
+ class PostSerializer < ApplicationSerializer
105
+ attributes :id
106
+ end
107
+ ````
108
+
109
+ ## Rails Integration
110
+
111
+ ActiveModelSerializers will automatically integrate with your Rails app,
112
+ so you won't need to update your controller.
113
+ This is a example of how the controller will look:
114
+
115
+ ```ruby
116
+ class PostsController < ApplicationController
117
+
118
+ def show
119
+ @post = Post.find(params[:id])
120
+ render json: @post
121
+ end
122
+
123
+ end
124
+ ```
125
+
126
+ If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
127
+ `Rails.application.routes.default_url_options`.
128
+
129
+ ```ruby
130
+ Rails.application.routes.default_url_options = {
131
+ host: 'example.com'
132
+ }
133
+ ```
@@ -0,0 +1,40 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Instrumentation
4
+
5
+ ActiveModelSerializers uses the
6
+ [ActiveSupport::Notification API](http://guides.rubyonrails.org/active_support_instrumentation.html#subscribing-to-an-event),
7
+ which allows for subscribing to events, such as for logging.
8
+
9
+ ## Events
10
+
11
+ Name:
12
+
13
+ `render.active_model_serializers`
14
+
15
+ Payload (example):
16
+
17
+ ```ruby
18
+ {
19
+ serializer: PostSerializer,
20
+ adapter: ActiveModelSerializers::Adapter::Attributes
21
+ }
22
+ ```
23
+
24
+ Subscribing:
25
+
26
+ ```ruby
27
+ ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |name, started, finished, unique_id, data|
28
+ # whatever
29
+ end
30
+ ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |*args|
31
+ event = ActiveSupport::Notifications::Event.new(*args)
32
+ # event.payload
33
+ # whatever
34
+ end
35
+ ```
36
+
37
+ ## [LogSubscriber](http://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html)
38
+
39
+ ActiveModelSerializers includes an `ActiveModelSerializers::LogSubscriber` that attaches to
40
+ `render.active_model_serializers`.
@@ -0,0 +1,40 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Key Transforms
4
+
5
+ Key Transforms modify the casing of keys and keys referenced in values in
6
+ serialized responses.
7
+
8
+ Provided key transforms:
9
+
10
+ | Option | Result |
11
+ |----|----|
12
+ | `:camel` | ExampleKey |
13
+ | `:camel_lower` | exampleKey |
14
+ | `:dash` | example-key |
15
+ | `:unaltered` | the original, unaltered key |
16
+ | `:underscore` | example_key |
17
+ | `nil` | use the adapter default |
18
+
19
+ Key translation precedence is as follows:
20
+
21
+ ##### Adapter option
22
+
23
+ `key_transform` is provided as an option via render.
24
+
25
+ ```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
26
+
27
+ ##### Configuration option
28
+
29
+ `key_transform` is set in `ActiveModelSerializers.config.key_transform`.
30
+
31
+ ```ActiveModelSerializers.config.key_transform = :camel_lower```
32
+
33
+ ##### Adapter default
34
+
35
+ Each adapter has a default transform configured:
36
+
37
+ | Adapter | Default Key Transform |
38
+ |----|----|
39
+ | `Json` | `:unaltered` |
40
+ | `JsonApi` | `:dash` |