active_model_serializers 0.10.7 → 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 (213) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -1
  3. data/README.md +20 -20
  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 +33 -18
  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 +2 -0
  15. data/lib/active_model/serializer/attribute.rb +2 -0
  16. data/lib/active_model/serializer/belongs_to_reflection.rb +2 -0
  17. data/lib/active_model/serializer/collection_serializer.rb +6 -6
  18. data/lib/active_model/serializer/concerns/caching.rb +7 -2
  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 +2 -0
  24. data/lib/active_model/serializer/has_one_reflection.rb +2 -0
  25. data/lib/active_model/serializer/lazy_association.rb +6 -2
  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 +9 -4
  30. data/lib/active_model/serializer/version.rb +3 -1
  31. data/lib/active_model_serializers.rb +20 -10
  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 +2 -0
  35. data/lib/active_model_serializers/adapter/json.rb +2 -0
  36. data/lib/active_model_serializers/adapter/json_api.rb +14 -9
  37. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +2 -0
  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 +2 -0
  43. data/lib/active_model_serializers/adapter/json_api/relationship.rb +2 -0
  44. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +3 -1
  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 +2 -0
  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 +2 -0
  60. data/lib/active_model_serializers/test/serializer.rb +2 -0
  61. data/lib/generators/rails/resource_override.rb +2 -0
  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 +2 -0
  67. metadata +70 -295
  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 -105
  72. data/.simplecov +0 -110
  73. data/.travis.yml +0 -52
  74. data/CODE_OF_CONDUCT.md +0 -74
  75. data/CONTRIBUTING.md +0 -105
  76. data/Gemfile +0 -72
  77. data/Rakefile +0 -74
  78. data/active_model_serializers.gemspec +0 -63
  79. data/appveyor.yml +0 -28
  80. data/bin/bench +0 -171
  81. data/bin/bench_regression +0 -316
  82. data/bin/rubocop +0 -38
  83. data/bin/serve_benchmark +0 -39
  84. data/docs/README.md +0 -41
  85. data/docs/STYLE.md +0 -58
  86. data/docs/general/adapters.md +0 -269
  87. data/docs/general/caching.md +0 -58
  88. data/docs/general/configuration_options.md +0 -185
  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 -21
  95. data/docs/general/rendering.md +0 -293
  96. data/docs/general/serializers.md +0 -483
  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 -140
  100. data/docs/howto/add_root_key.md +0 -62
  101. data/docs/howto/grape_integration.md +0 -42
  102. data/docs/howto/outside_controller_use.md +0 -66
  103. data/docs/howto/passing_arbitrary_options.md +0 -27
  104. data/docs/howto/serialize_poro.md +0 -73
  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 -147
  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/test/action_controller/adapter_selector_test.rb +0 -62
  115. data/test/action_controller/explicit_serializer_test.rb +0 -135
  116. data/test/action_controller/json/include_test.rb +0 -246
  117. data/test/action_controller/json_api/deserialization_test.rb +0 -112
  118. data/test/action_controller/json_api/errors_test.rb +0 -40
  119. data/test/action_controller/json_api/fields_test.rb +0 -66
  120. data/test/action_controller/json_api/linked_test.rb +0 -202
  121. data/test/action_controller/json_api/pagination_test.rb +0 -124
  122. data/test/action_controller/json_api/transform_test.rb +0 -189
  123. data/test/action_controller/lookup_proc_test.rb +0 -49
  124. data/test/action_controller/namespace_lookup_test.rb +0 -232
  125. data/test/action_controller/serialization_scope_name_test.rb +0 -235
  126. data/test/action_controller/serialization_test.rb +0 -472
  127. data/test/active_model_serializers/adapter_for_test.rb +0 -208
  128. data/test/active_model_serializers/json_pointer_test.rb +0 -22
  129. data/test/active_model_serializers/logging_test.rb +0 -77
  130. data/test/active_model_serializers/model_test.rb +0 -142
  131. data/test/active_model_serializers/railtie_test_isolated.rb +0 -68
  132. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +0 -161
  133. data/test/active_model_serializers/serialization_context_test_isolated.rb +0 -71
  134. data/test/active_model_serializers/test/schema_test.rb +0 -131
  135. data/test/active_model_serializers/test/serializer_test.rb +0 -62
  136. data/test/active_record_test.rb +0 -9
  137. data/test/adapter/attributes_test.rb +0 -40
  138. data/test/adapter/deprecation_test.rb +0 -100
  139. data/test/adapter/json/belongs_to_test.rb +0 -45
  140. data/test/adapter/json/collection_test.rb +0 -104
  141. data/test/adapter/json/has_many_test.rb +0 -53
  142. data/test/adapter/json/transform_test.rb +0 -93
  143. data/test/adapter/json_api/belongs_to_test.rb +0 -155
  144. data/test/adapter/json_api/collection_test.rb +0 -96
  145. data/test/adapter/json_api/errors_test.rb +0 -76
  146. data/test/adapter/json_api/fields_test.rb +0 -96
  147. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +0 -96
  148. data/test/adapter/json_api/has_many_test.rb +0 -173
  149. data/test/adapter/json_api/has_one_test.rb +0 -80
  150. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +0 -213
  151. data/test/adapter/json_api/json_api_test.rb +0 -33
  152. data/test/adapter/json_api/linked_test.rb +0 -413
  153. data/test/adapter/json_api/links_test.rb +0 -95
  154. data/test/adapter/json_api/pagination_links_test.rb +0 -206
  155. data/test/adapter/json_api/parse_test.rb +0 -137
  156. data/test/adapter/json_api/relationship_test.rb +0 -397
  157. data/test/adapter/json_api/resource_meta_test.rb +0 -100
  158. data/test/adapter/json_api/toplevel_jsonapi_test.rb +0 -82
  159. data/test/adapter/json_api/transform_test.rb +0 -512
  160. data/test/adapter/json_api/type_test.rb +0 -193
  161. data/test/adapter/json_test.rb +0 -46
  162. data/test/adapter/null_test.rb +0 -22
  163. data/test/adapter/polymorphic_test.rb +0 -218
  164. data/test/adapter_test.rb +0 -67
  165. data/test/array_serializer_test.rb +0 -22
  166. data/test/benchmark/app.rb +0 -65
  167. data/test/benchmark/benchmarking_support.rb +0 -67
  168. data/test/benchmark/bm_active_record.rb +0 -81
  169. data/test/benchmark/bm_adapter.rb +0 -38
  170. data/test/benchmark/bm_caching.rb +0 -119
  171. data/test/benchmark/bm_lookup_chain.rb +0 -83
  172. data/test/benchmark/bm_transform.rb +0 -45
  173. data/test/benchmark/config.ru +0 -3
  174. data/test/benchmark/controllers.rb +0 -83
  175. data/test/benchmark/fixtures.rb +0 -219
  176. data/test/cache_test.rb +0 -651
  177. data/test/collection_serializer_test.rb +0 -127
  178. data/test/fixtures/active_record.rb +0 -113
  179. data/test/fixtures/poro.rb +0 -225
  180. data/test/generators/scaffold_controller_generator_test.rb +0 -24
  181. data/test/generators/serializer_generator_test.rb +0 -75
  182. data/test/grape_test.rb +0 -196
  183. data/test/lint_test.rb +0 -49
  184. data/test/logger_test.rb +0 -20
  185. data/test/poro_test.rb +0 -9
  186. data/test/serializable_resource_test.rb +0 -79
  187. data/test/serializers/association_macros_test.rb +0 -37
  188. data/test/serializers/associations_test.rb +0 -468
  189. data/test/serializers/attribute_test.rb +0 -153
  190. data/test/serializers/attributes_test.rb +0 -52
  191. data/test/serializers/caching_configuration_test_isolated.rb +0 -170
  192. data/test/serializers/configuration_test.rb +0 -32
  193. data/test/serializers/fieldset_test.rb +0 -14
  194. data/test/serializers/meta_test.rb +0 -202
  195. data/test/serializers/options_test.rb +0 -32
  196. data/test/serializers/read_attribute_for_serialization_test.rb +0 -79
  197. data/test/serializers/reflection_test.rb +0 -427
  198. data/test/serializers/root_test.rb +0 -21
  199. data/test/serializers/serialization_test.rb +0 -55
  200. data/test/serializers/serializer_for_test.rb +0 -136
  201. data/test/serializers/serializer_for_with_namespace_test.rb +0 -88
  202. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  203. data/test/support/isolated_unit.rb +0 -84
  204. data/test/support/rails5_shims.rb +0 -53
  205. data/test/support/rails_app.rb +0 -38
  206. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  207. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +0 -6
  208. data/test/support/schemas/custom/show.json +0 -7
  209. data/test/support/schemas/hyper_schema.json +0 -93
  210. data/test/support/schemas/render_using_json_api.json +0 -43
  211. data/test/support/schemas/simple_json_pointers.json +0 -10
  212. data/test/support/serialization_testing.rb +0 -79
  213. data/test/test_helper.rb +0 -70
@@ -1,40 +0,0 @@
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`.
@@ -1,40 +0,0 @@
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` |
@@ -1,21 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- # Logging
4
-
5
- The default logger in a Rails application will be `Rails.logger`.
6
-
7
- When there is no `Rails.logger`, the default logger is an instance of
8
- `ActiveSupport::TaggedLogging` logging to STDOUT.
9
-
10
- You may customize the logger in an initializer, for example:
11
-
12
- ```ruby
13
- ActiveModelSerializers.logger = Logger.new(STDOUT)
14
- ```
15
-
16
- You can also disable the logger, just put this in `config/initializers/active_model_serializers.rb`:
17
-
18
- ```ruby
19
- require 'active_model_serializers'
20
- ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT)
21
- ```
@@ -1,293 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- # Rendering
4
-
5
- ### Implicit Serializer
6
-
7
- In your controllers, when you use `render :json`, Rails will now first search
8
- for a serializer for the object and use it if available.
9
-
10
- ```ruby
11
- class PostsController < ApplicationController
12
- def show
13
- @post = Post.find(params[:id])
14
-
15
- render json: @post
16
- end
17
- end
18
- ```
19
-
20
- In this case, Rails will look for a serializer named `PostSerializer`, and if
21
- it exists, use it to serialize the `Post`.
22
-
23
- ### Explicit Serializer
24
-
25
- If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
26
-
27
- #### 1. For a resource:
28
-
29
- ```ruby
30
- render json: @post, serializer: PostPreviewSerializer
31
- ```
32
-
33
- #### 2. For a resource collection:
34
-
35
- Specify the serializer for each resource with `each_serializer`
36
-
37
- ```ruby
38
- render json: @posts, each_serializer: PostPreviewSerializer
39
- ```
40
-
41
- The default serializer for collections is `CollectionSerializer`.
42
-
43
- Specify the collection serializer with the `serializer` option.
44
-
45
- ```ruby
46
- render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
47
- ```
48
-
49
- ## Serializing non-ActiveRecord objects
50
-
51
- See [README](../../README.md#what-does-a-serializable-resource-look-like)
52
-
53
- ## SerializableResource options
54
-
55
- See [README](../../README.md#activemodelserializersserializableresource)
56
-
57
- ### adapter_opts
58
-
59
- #### fields
60
-
61
- If you are using `json` or `attributes` adapter
62
- ```ruby
63
- render json: @user, fields: [:access_token]
64
- ```
65
-
66
- See [Fields](fields.md) for more information.
67
-
68
- #### adapter
69
-
70
- This option lets you explicitly set the adapter to be used by passing a registered adapter. Your options are `:attributes`, `:json`, and `:json_api`.
71
-
72
- ```
73
- ActiveModel::Serializer.config.adapter = :json_api
74
- ```
75
-
76
- #### key_transform
77
-
78
- ```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
79
-
80
- See [Key Transforms](key_transforms.md) for more information.
81
-
82
- #### meta
83
-
84
- A `meta` member can be used to include non-standard meta-information. `meta` can
85
- be utilized in several levels in a response.
86
-
87
- ##### Top-level
88
-
89
- To set top-level `meta` in a response, specify it in the `render` call.
90
-
91
- ```ruby
92
- render json: @post, meta: { total: 10 }
93
- ```
94
-
95
- The key can be customized using `meta_key` option.
96
-
97
- ```ruby
98
- render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
99
- ```
100
-
101
- `meta` will only be included in your response if you are using an Adapter that
102
- supports `root`, e.g., `JsonApi` and `Json` adapters. The default adapter,
103
- `Attributes` does not have `root`.
104
-
105
-
106
- ##### Resource-level
107
-
108
- To set resource-level `meta` in a response, define meta in a serializer with one
109
- of the following methods:
110
-
111
- As a single, static string.
112
-
113
- ```ruby
114
- meta stuff: 'value'
115
- ```
116
-
117
- As a block containing a Hash.
118
-
119
- ```ruby
120
- meta do
121
- {
122
- rating: 4,
123
- comments_count: object.comments.count
124
- }
125
- end
126
- ```
127
-
128
-
129
- #### links
130
-
131
- If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
132
- `Rails.application.routes.default_url_options`.
133
-
134
- ##### Top-level
135
-
136
- JsonApi supports a [links object](http://jsonapi.org/format/#document-links) to be specified at top-level, that you can specify in the `render`:
137
-
138
- ```ruby
139
- links_object = {
140
- href: "http://example.com/api/posts",
141
- meta: {
142
- count: 10
143
- }
144
- }
145
- render json: @posts, links: links_object
146
- ```
147
-
148
- That's the result:
149
-
150
- ```json
151
- {
152
- "data": [
153
- {
154
- "type": "posts",
155
- "id": "1",
156
- "attributes": {
157
- "title": "JSON API is awesome!",
158
- "body": "You should be using JSON API",
159
- "created": "2015-05-22T14:56:29.000Z",
160
- "updated": "2015-05-22T14:56:28.000Z"
161
- }
162
- }
163
- ],
164
- "links": {
165
- "href": "http://example.com/api/posts",
166
- "meta": {
167
- "count": 10
168
- }
169
- }
170
- }
171
- ```
172
-
173
- This feature is specific to JsonApi, so you have to use the use the [JsonApi Adapter](adapters.md#jsonapi)
174
-
175
-
176
- ##### Resource-level
177
-
178
- In your serializer, define each link in one of the following methods:
179
-
180
- As a static string
181
-
182
- ```ruby
183
- link :link_name, 'https://example.com/resource'
184
- ```
185
-
186
- As a block to be evaluated. When using Rails, URL helpers are available.
187
- Ensure your application sets `Rails.application.routes.default_url_options`.
188
-
189
- ```ruby
190
- link :link_name_ do
191
- "https://example.com/resource/#{object.id}"
192
- end
193
-
194
- link(:link_name) { "https://example.com/resource/#{object.id}" }
195
-
196
- link(:link_name) { resource_url(object) }
197
-
198
- link(:link_name) { url_for(controller: 'controller_name', action: 'index', only_path: false) }
199
-
200
- ```
201
-
202
- ### serializer_opts
203
-
204
- #### include
205
-
206
- See [Adapters: Include Option](/docs/general/adapters.md#include-option).
207
-
208
- #### Overriding the root key
209
-
210
- Overriding the resource root only applies when using the JSON adapter.
211
-
212
- Normally, the resource root is derived from the class name of the resource being serialized.
213
- e.g. `UserPostSerializer.new(UserPost.new)` will be serialized with the root `user_post` or `user_posts` according the adapter collection pluralization rules.
214
-
215
- When using the JSON adapter in your initializer (ActiveModelSerializers.config.adapter = :json), or passing in the adapter in your render call, you can specify the root by passing it as an argument to `render`. For example:
216
-
217
- ```ruby
218
- render json: @user_post, root: "admin_post", adapter: :json
219
- ```
220
-
221
- This will be rendered as:
222
- ```json
223
- {
224
- "admin_post": {
225
- "title": "how to do open source"
226
- }
227
- }
228
- ```
229
- Note: the `Attributes` adapter (default) does not include a resource root. You also will not be able to create a single top-level root if you are using the :json_api adapter.
230
-
231
- #### namespace
232
-
233
- The namespace for serializer lookup is based on the controller.
234
-
235
- To configure the implicit namespace, in your controller, create a before filter
236
-
237
- ```ruby
238
- before_action do
239
- self.namespace_for_serializer = Api::V2
240
- end
241
- ```
242
-
243
- `namespace` can also be passed in as a render option:
244
-
245
-
246
- ```ruby
247
- @post = Post.first
248
- render json: @post, namespace: Api::V2
249
- ```
250
-
251
- This tells the serializer lookup to check for the existence of `Api::V2::PostSerializer`, and if any relations are rendered with `@post`, they will also utilize the `Api::V2` namespace.
252
-
253
- The `namespace` can be any object whose namespace can be represented by string interpolation (i.e. by calling to_s)
254
- - Module `Api::V2`
255
- - String `'Api::V2'`
256
- - Symbol `:'Api::V2'`
257
-
258
- Note that by using a string and symbol, Ruby will assume the namespace is defined at the top level.
259
-
260
-
261
- #### serializer
262
-
263
- Specify which serializer to use if you want to use a serializer other than the default.
264
-
265
- For a single resource:
266
-
267
- ```ruby
268
- @post = Post.first
269
- render json: @post, serializer: SpecialPostSerializer
270
- ```
271
-
272
- To specify which serializer to use on individual items in a collection (i.e., an `index` action), use `each_serializer`:
273
-
274
- ```ruby
275
- @posts = Post.all
276
- render json: @posts, each_serializer: SpecialPostSerializer
277
- ```
278
-
279
- #### scope
280
-
281
- See [Serializers: Scope](/docs/general/serializers.md#scope).
282
-
283
- #### scope_name
284
-
285
- See [Serializers: Scope](/docs/general/serializers.md#scope).
286
-
287
- ## Using a serializer without `render`
288
-
289
- See [Usage outside of a controller](../howto/outside_controller_use.md#serializing-before-controller-render).
290
-
291
- ## Pagination
292
-
293
- See [How to add pagination links](../howto/add_pagination_links.md).
@@ -1,483 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- # Serializers
4
-
5
- Given a serializer class:
6
-
7
- ```ruby
8
- class SomeSerializer < ActiveModel::Serializer
9
- end
10
- ```
11
-
12
- The following methods may be defined in it:
13
-
14
- ### Attributes
15
-
16
- #### ::attributes
17
-
18
- Serialization of the resource `title` and `body`
19
-
20
- | In Serializer | #attributes |
21
- |---------------------------- |-------------|
22
- | `attributes :title, :body` | `{ title: 'Some Title', body: 'Some Body' }`
23
- | `attributes :title, :body`<br>`def body "Special #{object.body}" end` | `{ title: 'Some Title', body: 'Special Some Body' }`
24
-
25
-
26
- #### ::attribute
27
-
28
- Serialization of the resource `title`
29
-
30
- | In Serializer | #attributes |
31
- |---------------------------- |-------------|
32
- | `attribute :title` | `{ title: 'Some Title' } `
33
- | `attribute :title, key: :name` | `{ name: 'Some Title' } `
34
- | `attribute(:title) { 'A Different Title'}` | `{ title: 'A Different Title' } `
35
- | `attribute :title`<br>`def title 'A Different Title' end` | `{ title: 'A Different Title' }`
36
-
37
- An `if` or `unless` option can make an attribute conditional. It takes a symbol of a method name on the serializer, or a lambda literal.
38
-
39
- e.g.
40
-
41
- ```ruby
42
- attribute :private_data, if: :is_current_user?
43
- attribute :another_private_data, if: -> { scope.admin? }
44
-
45
- def is_current_user?
46
- object.id == current_user.id
47
- end
48
- ```
49
-
50
- ### Associations
51
-
52
- The interface for associations is, generically:
53
-
54
- > `association_type(association_name, options, &block)`
55
-
56
- Where:
57
-
58
- - `association_type` may be `has_one`, `has_many`, `belongs_to`.
59
- - `association_name` is a method name the serializer calls.
60
- - optional: `options` may be:
61
- - `key:` The name used for the serialized association.
62
- - `serializer:`
63
- - `if:`
64
- - `unless:`
65
- - `virtual_value:`
66
- - `polymorphic:` defines if polymorphic relation type should be nested in serialized association.
67
- - `type:` the resource type as used by JSON:API, especially on a `belongs_to` relationship.
68
- - `class_name:` used to determine `type` when `type` not given
69
- - `foreign_key:` used by JSON:API on a `belongs_to` relationship to avoid unnecessarily loading the association object.
70
- - `namespace:` used when looking up the serializer and `serializer` is not given. Falls back to the parent serializer's `:namespace` instance options, which, when present, comes from the render options. See [Rendering#namespace](rendering.md#namespace] for more details.
71
- - optional: `&block` is a context that returns the association's attributes.
72
- - prevents `association_name` method from being called.
73
- - return value of block is used as the association value.
74
- - yields the `serializer` to the block.
75
- - `include_data false` prevents the `data` key from being rendered in the JSON API relationship.
76
-
77
- #### ::has_one
78
-
79
- e.g.
80
-
81
- ```ruby
82
- has_one :bio
83
- has_one :blog, key: :site
84
- has_one :maker, virtual_value: { id: 1 }
85
-
86
- has_one :blog do |serializer|
87
- serializer.cached_blog
88
- end
89
-
90
- def cached_blog
91
- cache_store.fetch("cached_blog:#{object.updated_at}") do
92
- Blog.find(object.blog_id)
93
- end
94
- end
95
- ```
96
-
97
- ```ruby
98
- has_one :blog, if: :show_blog?
99
- # you can also use a string or lambda
100
- # has_one :blog, if: 'scope.admin?'
101
- # has_one :blog, if: -> (serializer) { serializer.scope.admin? }
102
- # has_one :blog, if: -> { scope.admin? }
103
-
104
- def show_blog?
105
- scope.admin?
106
- end
107
- ```
108
-
109
- #### ::has_many
110
-
111
- e.g.
112
-
113
- ```ruby
114
- has_many :comments
115
- has_many :comments, key: :reviews
116
- has_many :comments, serializer: CommentPreviewSerializer
117
- has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]
118
- has_many :comments, key: :last_comments do
119
- last(1)
120
- end
121
- ```
122
-
123
- #### ::belongs_to
124
-
125
- e.g.
126
-
127
- ```ruby
128
- belongs_to :author, serializer: AuthorPreviewSerializer
129
- belongs_to :author, key: :writer
130
- belongs_to :post
131
- belongs_to :blog
132
- def blog
133
- Blog.new(id: 999, name: 'Custom blog')
134
- end
135
- ```
136
-
137
- ### Polymorphic Relationships
138
-
139
- Polymorphic relationships are serialized by specifying the relationship, like any other association. For example:
140
-
141
- ```ruby
142
- class PictureSerializer < ActiveModel::Serializer
143
- has_one :imageable
144
- end
145
- ```
146
-
147
- You can specify the serializers by [overriding serializer_for](serializers.md#overriding-association-serializer-lookup). For more context about polymorphic relationships, see the [tests](../../test/adapter/polymorphic_test.rb) for each adapter.
148
-
149
- ### Caching
150
-
151
- #### ::cache
152
-
153
- e.g.
154
-
155
- ```ruby
156
- cache key: 'post', expires_in: 0.1, skip_digest: true
157
- cache expires_in: 1.day, skip_digest: true
158
- cache key: 'writer', skip_digest: true
159
- cache only: [:name], skip_digest: true
160
- cache except: [:content], skip_digest: true
161
- cache key: 'blog'
162
- cache only: [:id]
163
- ```
164
-
165
- #### #cache_key
166
-
167
- e.g.
168
-
169
- ```ruby
170
- # Uses a custom non-time-based cache key
171
- def cache_key
172
- "#{self.class.name.downcase}/#{self.id}"
173
- end
174
- ```
175
-
176
- ### Other
177
-
178
- #### ::type
179
-
180
- When using the `:json_api` adapter, the `::type` method defines the JSONAPI [type](http://jsonapi.org/format/#document-resource-object-identification) that will be rendered for this serializer.
181
-
182
- When using the `:json` adapter, the `::type` method defines the name of the root element.
183
-
184
- It either takes a `String` or `Symbol` as parameter.
185
-
186
- Note: This method is useful only when using the `:json_api` or `:json` adapter.
187
-
188
- Examples:
189
- ```ruby
190
- class UserProfileSerializer < ActiveModel::Serializer
191
- type 'profile'
192
-
193
- attribute :name
194
- end
195
- class AuthorProfileSerializer < ActiveModel::Serializer
196
- type :profile
197
-
198
- attribute :name
199
- end
200
- ```
201
-
202
- With the `:json_api` adapter, the previous serializers would be rendered as:
203
-
204
- ``` json
205
- {
206
- "data": {
207
- "id": "1",
208
- "type": "profile",
209
- "attributes": {
210
- "name": "Julia"
211
- }
212
- }
213
- }
214
- ```
215
-
216
- With the `:json` adapter, the previous serializer would be rendered as:
217
-
218
- ``` json
219
- {
220
- "profile": {
221
- "name": "Julia"
222
- }
223
- }
224
- ```
225
-
226
- #### ::link
227
-
228
- ```ruby
229
- link :self do
230
- href "https://example.com/link_author/#{object.id}"
231
- end
232
- link(:author) { link_author_url(object) }
233
- link(:link_authors) { link_authors_url }
234
- link :other, 'https://example.com/resource'
235
- link(:posts) { link_author_posts_url(object) }
236
- ```
237
-
238
- #### #object
239
-
240
- The object being serialized.
241
-
242
- #### #root
243
-
244
- Resource root which is included in `JSON` adapter. As you can see at [Adapters Document](adapters.md), `Attribute` adapter (default) and `JSON API` adapter does not include root at top level.
245
- By default, the resource root comes from the `model_name` of the serialized object's class.
246
-
247
- There are several ways to specify root:
248
- * [Overriding the root key](rendering.md#overriding-the-root-key)
249
- * [Setting `type`](serializers.md#type)
250
- * Specifying the `root` option, e.g. `root: 'specific_name'`, during the serializer's initialization:
251
-
252
- ```ruby
253
- ActiveModelSerializers::SerializableResource.new(foo, root: 'bar')
254
- ```
255
-
256
- #### #scope
257
-
258
- Allows you to include in the serializer access to an external method.
259
-
260
- It's intended to provide an authorization context to the serializer, so that
261
- you may e.g. show an admin all comments on a post, else only published comments.
262
-
263
- - `scope` is a method on the serializer instance that comes from `options[:scope]`. It may be nil.
264
- - `scope_name` is an option passed to the new serializer (`options[:scope_name]`). The serializer
265
- defines a method with that name that calls the `scope`, e.g. `def current_user; scope; end`.
266
- Note: it does not define the method if the serializer instance responds to it.
267
-
268
- That's a lot of words, so here's some examples:
269
-
270
- First, let's assume the serializer is instantiated in the controller, since that's the usual scenario.
271
- We'll refer to the serialization context as `controller`.
272
-
273
- | options | `Serializer#scope` | method definition |
274
- |-------- | ------------------|--------------------|
275
- | `scope: current_user, scope_name: :current_user` | `current_user` | `Serializer#current_user` calls `controller.current_user`
276
- | `scope: view_context, scope_name: :view_context` | `view_context` | `Serializer#view_context` calls `controller.view_context`
277
-
278
- We can take advantage of the scope to customize the objects returned based
279
- on the current user (scope).
280
-
281
- For example, we can limit the posts the current user sees to those they created:
282
-
283
- ```ruby
284
- class PostSerializer < ActiveModel::Serializer
285
- attributes :id, :title, :body
286
-
287
- # scope comments to those created_by the current user
288
- has_many :comments do
289
- object.comments.where(created_by: current_user)
290
- end
291
- end
292
- ```
293
-
294
- Whether you write the method as above or as `object.comments.where(created_by: scope)`
295
- is a matter of preference (assuming `scope_name` has been set).
296
-
297
- Keep in mind that the scope can be set to any available controller reference. This can be utilized to provide access to any other data scopes or presentation helpers.
298
-
299
- ##### Controller Authorization Context
300
-
301
- In the controller, the scope/scope_name options are equal to
302
- the [`serialization_scope`method](https://github.com/rails-api/active_model_serializers/blob/d02cd30fe55a3ea85e1d351b6e039620903c1871/lib/action_controller/serialization.rb#L13-L20),
303
- which is `:current_user`, by default.
304
-
305
- Specifically, the `scope_name` is defaulted to `:current_user`, and may be set as
306
- `serialization_scope :view_context`. The `scope` is set to `send(scope_name)` when `scope_name` is
307
- present and the controller responds to `scope_name`.
308
-
309
- Thus, in a serializer, the controller provides `current_user` as the
310
- current authorization scope when you call `render :json`.
311
-
312
- **IMPORTANT**: Since the scope is set at render, you may want to customize it so that `current_user` isn't
313
- called on every request. This was [also a problem](https://github.com/rails-api/active_model_serializers/pull/1252#issuecomment-159810477)
314
- in [`0.9`](https://github.com/rails-api/active_model_serializers/tree/0-9-stable#customizing-scope).
315
-
316
- We can change the scope from `current_user` to `view_context`, which is included in subclasses of `ActionController::Base`.
317
-
318
- ```diff
319
- class SomeController < ActionController::Base
320
- + serialization_scope :view_context
321
-
322
- def current_user
323
- User.new(id: 2, name: 'Bob', admin: true)
324
- end
325
-
326
- def edit
327
- user = User.new(id: 1, name: 'Pete')
328
- render json: user, serializer: AdminUserSerializer, adapter: :json_api
329
- end
330
- end
331
- ```
332
-
333
- We could then use the controller method `view_context` in our serializer, like so:
334
-
335
- ```diff
336
- class AdminUserSerializer < ActiveModel::Serializer
337
- attributes :id, :name, :can_edit
338
-
339
- def can_edit?
340
- + view_context.current_user.admin?
341
- end
342
- end
343
- ```
344
-
345
- So that when we render the `#edit` action, we'll get
346
-
347
- ```json
348
- {"data":{"id":"1","type":"users","attributes":{"name":"Pete","can_edit":true}}}
349
- ```
350
-
351
- Where `can_edit` is `view_context.current_user.admin?` (true).
352
-
353
- You can also tell what to set as `serialization_scope` for specific actions.
354
-
355
- For example, use `admin_user` only for `Admin::PostSerializer` and `current_user` for rest.
356
-
357
- ```ruby
358
- class PostsController < ActionController::Base
359
-
360
- before_action only: :edit do
361
- self.class.serialization_scope :admin_user
362
- end
363
-
364
- def show
365
- render json: @post, serializer: PostSerializer
366
- end
367
-
368
- def edit
369
- @post.save
370
- render json: @post, serializer: Admin::PostSerializer
371
- end
372
-
373
- private
374
-
375
- def admin_user
376
- User.new(id: 2, name: 'Bob', admin: true)
377
- end
378
-
379
- def current_user
380
- User.new(id: 2, name: 'Bob', admin: false)
381
- end
382
- end
383
- ```
384
- Note that any controller reference which provides the desired scope is acceptable, such as another controller method for loading a different resource or reference to helpers. For example, `ActionController::API` does not include `ActionView::ViewContext`, and would need a different reference for passing any helpers into a serializer via `serialization_scope`.
385
-
386
- #### #read_attribute_for_serialization(key)
387
-
388
- The serialized value for a given key. e.g. `read_attribute_for_serialization(:title) #=> 'Hello World'`
389
-
390
- #### #links
391
-
392
- Allows you to modify the `links` node. By default, this node will be populated with the attributes set using the [::link](#link) method. Using `links: nil` will remove the `links` node.
393
-
394
- ```ruby
395
- ActiveModelSerializers::SerializableResource.new(
396
- @post,
397
- adapter: :json_api,
398
- links: {
399
- self: {
400
- href: 'http://example.com/posts',
401
- meta: {
402
- stuff: 'value'
403
- }
404
- }
405
- }
406
- )
407
- ```
408
-
409
- #### #json_key
410
-
411
- Returns the key used by the adapter as the resource root. See [root](#root) for more information.
412
-
413
- ## Examples
414
-
415
- Given two models, a `Post(title: string, body: text)` and a
416
- `Comment(name: string, body: text, post_id: integer)`, you will have two
417
- serializers:
418
-
419
- ```ruby
420
- class PostSerializer < ActiveModel::Serializer
421
- cache key: 'posts', expires_in: 3.hours
422
- attributes :title, :body
423
-
424
- has_many :comments
425
- end
426
- ```
427
-
428
- and
429
-
430
- ```ruby
431
- class CommentSerializer < ActiveModel::Serializer
432
- attributes :name, :body
433
-
434
- belongs_to :post
435
- end
436
- ```
437
-
438
- Generally speaking, you, as a user of ActiveModelSerializers, will write (or generate) these
439
- serializer classes.
440
-
441
- ## More Info
442
-
443
- For more information, see [the Serializer class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer.rb)
444
-
445
- ## Overriding association methods
446
-
447
- To override an association, call `has_many`, `has_one` or `belongs_to` with a block:
448
-
449
- ```ruby
450
- class PostSerializer < ActiveModel::Serializer
451
- has_many :comments do
452
- object.comments.active
453
- end
454
- end
455
- ```
456
-
457
- ## Overriding attribute methods
458
-
459
- To override an attribute, call `attribute` with a block:
460
-
461
- ```ruby
462
- class PostSerializer < ActiveModel::Serializer
463
- attribute :body do
464
- object.body.downcase
465
- end
466
- end
467
- ```
468
-
469
- ## Overriding association serializer lookup
470
-
471
- If you want to define a specific serializer lookup for your associations, you can override
472
- the `ActiveModel::Serializer.serializer_for` method to return a serializer class based on defined conditions.
473
-
474
- ```ruby
475
- class MySerializer < ActiveModel::Serializer
476
- def self.serializer_for(model, options)
477
- return SparseAdminSerializer if model.class == 'Admin'
478
- super
479
- end
480
-
481
- # the rest of the serializer
482
- end
483
- ```