active_model_serializers 0.10.0 → 0.10.13

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 (215) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +239 -2
  3. data/README.md +171 -34
  4. data/lib/action_controller/serialization.rb +23 -3
  5. data/lib/active_model/serializable_resource.rb +2 -0
  6. data/lib/active_model/serializer/adapter/attributes.rb +2 -0
  7. data/lib/active_model/serializer/adapter/base.rb +4 -0
  8. data/lib/active_model/serializer/adapter/json.rb +2 -0
  9. data/lib/active_model/serializer/adapter/json_api.rb +2 -0
  10. data/lib/active_model/serializer/adapter/null.rb +2 -0
  11. data/lib/active_model/serializer/adapter.rb +2 -0
  12. data/lib/active_model/serializer/array_serializer.rb +10 -5
  13. data/lib/active_model/serializer/association.rb +64 -10
  14. data/lib/active_model/serializer/attribute.rb +2 -0
  15. data/lib/active_model/serializer/belongs_to_reflection.rb +6 -3
  16. data/lib/active_model/serializer/collection_serializer.rb +48 -13
  17. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +89 -117
  18. data/lib/active_model/serializer/error_serializer.rb +13 -7
  19. data/lib/active_model/serializer/errors_serializer.rb +27 -20
  20. data/lib/active_model/serializer/field.rb +2 -0
  21. data/lib/active_model/serializer/fieldset.rb +3 -1
  22. data/lib/active_model/serializer/has_many_reflection.rb +5 -3
  23. data/lib/active_model/serializer/has_one_reflection.rb +3 -4
  24. data/lib/active_model/serializer/lazy_association.rb +99 -0
  25. data/lib/active_model/serializer/link.rb +23 -0
  26. data/lib/active_model/serializer/lint.rb +136 -130
  27. data/lib/active_model/serializer/null.rb +2 -0
  28. data/lib/active_model/serializer/reflection.rb +130 -65
  29. data/lib/active_model/serializer/version.rb +3 -1
  30. data/lib/active_model/serializer.rb +321 -86
  31. data/lib/active_model_serializers/adapter/attributes.rb +17 -57
  32. data/lib/active_model_serializers/adapter/base.rb +41 -39
  33. data/lib/active_model_serializers/adapter/json.rb +2 -0
  34. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
  35. data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
  36. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
  37. data/lib/active_model_serializers/adapter/json_api/link.rb +3 -1
  38. data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
  39. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +52 -20
  40. data/lib/active_model_serializers/adapter/json_api/relationship.rb +77 -23
  41. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +41 -10
  42. data/lib/active_model_serializers/adapter/json_api.rb +84 -65
  43. data/lib/active_model_serializers/adapter/null.rb +2 -0
  44. data/lib/active_model_serializers/adapter.rb +9 -1
  45. data/lib/active_model_serializers/callbacks.rb +2 -0
  46. data/lib/active_model_serializers/deprecate.rb +3 -2
  47. data/lib/active_model_serializers/deserialization.rb +4 -0
  48. data/lib/active_model_serializers/json_pointer.rb +2 -0
  49. data/lib/active_model_serializers/logging.rb +2 -0
  50. data/lib/active_model_serializers/lookup_chain.rb +82 -0
  51. data/lib/active_model_serializers/model/caching.rb +26 -0
  52. data/lib/active_model_serializers/model.rb +111 -28
  53. data/lib/active_model_serializers/railtie.rb +7 -1
  54. data/lib/active_model_serializers/register_jsonapi_renderer.rb +46 -31
  55. data/lib/active_model_serializers/serializable_resource.rb +10 -7
  56. data/lib/active_model_serializers/serialization_context.rb +12 -3
  57. data/lib/active_model_serializers/test/schema.rb +4 -2
  58. data/lib/active_model_serializers/test/serializer.rb +2 -0
  59. data/lib/active_model_serializers/test.rb +2 -0
  60. data/lib/active_model_serializers.rb +35 -10
  61. data/lib/generators/rails/resource_override.rb +3 -1
  62. data/lib/generators/rails/serializer_generator.rb +6 -4
  63. data/lib/grape/active_model_serializers.rb +9 -5
  64. data/lib/grape/formatters/active_model_serializers.rb +21 -2
  65. data/lib/grape/helpers/active_model_serializers.rb +3 -0
  66. data/lib/tasks/rubocop.rake +55 -0
  67. metadata +104 -296
  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 -104
  72. data/.rubocop_todo.yml +0 -167
  73. data/.simplecov +0 -110
  74. data/.travis.yml +0 -43
  75. data/CONTRIBUTING.md +0 -105
  76. data/Gemfile +0 -53
  77. data/Rakefile +0 -103
  78. data/active_model_serializers.gemspec +0 -66
  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 -126
  84. data/docs/README.md +0 -40
  85. data/docs/STYLE.md +0 -58
  86. data/docs/general/adapters.md +0 -245
  87. data/docs/general/caching.md +0 -52
  88. data/docs/general/configuration_options.md +0 -100
  89. data/docs/general/deserialization.md +0 -100
  90. data/docs/general/getting_started.md +0 -133
  91. data/docs/general/instrumentation.md +0 -40
  92. data/docs/general/key_transforms.md +0 -40
  93. data/docs/general/logging.md +0 -14
  94. data/docs/general/rendering.md +0 -255
  95. data/docs/general/serializers.md +0 -372
  96. data/docs/how-open-source-maintained.jpg +0 -0
  97. data/docs/howto/add_pagination_links.md +0 -139
  98. data/docs/howto/add_root_key.md +0 -51
  99. data/docs/howto/outside_controller_use.md +0 -58
  100. data/docs/howto/passing_arbitrary_options.md +0 -27
  101. data/docs/howto/serialize_poro.md +0 -32
  102. data/docs/howto/test.md +0 -152
  103. data/docs/integrations/ember-and-json-api.md +0 -112
  104. data/docs/integrations/grape.md +0 -19
  105. data/docs/jsonapi/errors.md +0 -56
  106. data/docs/jsonapi/schema/schema.json +0 -366
  107. data/docs/jsonapi/schema.md +0 -151
  108. data/docs/rfcs/0000-namespace.md +0 -106
  109. data/docs/rfcs/template.md +0 -15
  110. data/lib/active_model/serializer/associations.rb +0 -100
  111. data/lib/active_model/serializer/attributes.rb +0 -82
  112. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  113. data/lib/active_model/serializer/configuration.rb +0 -35
  114. data/lib/active_model/serializer/include_tree.rb +0 -111
  115. data/lib/active_model/serializer/links.rb +0 -35
  116. data/lib/active_model/serializer/meta.rb +0 -29
  117. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  118. data/lib/active_model/serializer/type.rb +0 -25
  119. data/lib/active_model_serializers/key_transform.rb +0 -70
  120. data/test/action_controller/adapter_selector_test.rb +0 -53
  121. data/test/action_controller/explicit_serializer_test.rb +0 -134
  122. data/test/action_controller/json/include_test.rb +0 -167
  123. data/test/action_controller/json_api/deserialization_test.rb +0 -112
  124. data/test/action_controller/json_api/errors_test.rb +0 -41
  125. data/test/action_controller/json_api/linked_test.rb +0 -197
  126. data/test/action_controller/json_api/pagination_test.rb +0 -116
  127. data/test/action_controller/json_api/transform_test.rb +0 -181
  128. data/test/action_controller/serialization_scope_name_test.rb +0 -229
  129. data/test/action_controller/serialization_test.rb +0 -469
  130. data/test/active_model_serializers/adapter_for_test.rb +0 -208
  131. data/test/active_model_serializers/json_pointer_test.rb +0 -20
  132. data/test/active_model_serializers/key_transform_test.rb +0 -263
  133. data/test/active_model_serializers/logging_test.rb +0 -77
  134. data/test/active_model_serializers/model_test.rb +0 -9
  135. data/test/active_model_serializers/railtie_test_isolated.rb +0 -63
  136. data/test/active_model_serializers/serialization_context_test_isolated.rb +0 -58
  137. data/test/active_model_serializers/test/schema_test.rb +0 -130
  138. data/test/active_model_serializers/test/serializer_test.rb +0 -62
  139. data/test/active_record_test.rb +0 -9
  140. data/test/adapter/deprecation_test.rb +0 -100
  141. data/test/adapter/json/belongs_to_test.rb +0 -45
  142. data/test/adapter/json/collection_test.rb +0 -90
  143. data/test/adapter/json/has_many_test.rb +0 -45
  144. data/test/adapter/json/transform_test.rb +0 -93
  145. data/test/adapter/json_api/belongs_to_test.rb +0 -155
  146. data/test/adapter/json_api/collection_test.rb +0 -95
  147. data/test/adapter/json_api/errors_test.rb +0 -78
  148. data/test/adapter/json_api/fields_test.rb +0 -87
  149. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  150. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +0 -96
  151. data/test/adapter/json_api/has_many_test.rb +0 -144
  152. data/test/adapter/json_api/has_one_test.rb +0 -80
  153. data/test/adapter/json_api/json_api_test.rb +0 -35
  154. data/test/adapter/json_api/linked_test.rb +0 -392
  155. data/test/adapter/json_api/links_test.rb +0 -93
  156. data/test/adapter/json_api/pagination_links_test.rb +0 -166
  157. data/test/adapter/json_api/parse_test.rb +0 -137
  158. data/test/adapter/json_api/relationship_test.rb +0 -161
  159. data/test/adapter/json_api/relationships_test.rb +0 -199
  160. data/test/adapter/json_api/resource_identifier_test.rb +0 -85
  161. data/test/adapter/json_api/resource_meta_test.rb +0 -100
  162. data/test/adapter/json_api/toplevel_jsonapi_test.rb +0 -82
  163. data/test/adapter/json_api/transform_test.rb +0 -502
  164. data/test/adapter/json_api/type_test.rb +0 -61
  165. data/test/adapter/json_test.rb +0 -45
  166. data/test/adapter/null_test.rb +0 -23
  167. data/test/adapter/polymorphic_test.rb +0 -171
  168. data/test/adapter_test.rb +0 -67
  169. data/test/array_serializer_test.rb +0 -22
  170. data/test/benchmark/app.rb +0 -65
  171. data/test/benchmark/benchmarking_support.rb +0 -67
  172. data/test/benchmark/bm_caching.rb +0 -119
  173. data/test/benchmark/bm_transform.rb +0 -34
  174. data/test/benchmark/config.ru +0 -3
  175. data/test/benchmark/controllers.rb +0 -84
  176. data/test/benchmark/fixtures.rb +0 -219
  177. data/test/cache_test.rb +0 -485
  178. data/test/collection_serializer_test.rb +0 -110
  179. data/test/fixtures/active_record.rb +0 -78
  180. data/test/fixtures/poro.rb +0 -282
  181. data/test/generators/scaffold_controller_generator_test.rb +0 -24
  182. data/test/generators/serializer_generator_test.rb +0 -57
  183. data/test/grape_test.rb +0 -82
  184. data/test/include_tree/from_include_args_test.rb +0 -26
  185. data/test/include_tree/from_string_test.rb +0 -94
  186. data/test/include_tree/include_args_to_hash_test.rb +0 -64
  187. data/test/lint_test.rb +0 -49
  188. data/test/logger_test.rb +0 -18
  189. data/test/poro_test.rb +0 -9
  190. data/test/serializable_resource_test.rb +0 -83
  191. data/test/serializers/association_macros_test.rb +0 -36
  192. data/test/serializers/associations_test.rb +0 -295
  193. data/test/serializers/attribute_test.rb +0 -151
  194. data/test/serializers/attributes_test.rb +0 -52
  195. data/test/serializers/caching_configuration_test_isolated.rb +0 -170
  196. data/test/serializers/configuration_test.rb +0 -32
  197. data/test/serializers/fieldset_test.rb +0 -14
  198. data/test/serializers/meta_test.rb +0 -196
  199. data/test/serializers/options_test.rb +0 -21
  200. data/test/serializers/read_attribute_for_serialization_test.rb +0 -79
  201. data/test/serializers/root_test.rb +0 -21
  202. data/test/serializers/serialization_test.rb +0 -55
  203. data/test/serializers/serializer_for_test.rb +0 -134
  204. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  205. data/test/support/isolated_unit.rb +0 -79
  206. data/test/support/rails5_shims.rb +0 -47
  207. data/test/support/rails_app.rb +0 -45
  208. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  209. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +0 -6
  210. data/test/support/schemas/custom/show.json +0 -7
  211. data/test/support/schemas/hyper_schema.json +0 -93
  212. data/test/support/schemas/render_using_json_api.json +0 -43
  213. data/test/support/schemas/simple_json_pointers.json +0 -10
  214. data/test/support/serialization_testing.rb +0 -53
  215. data/test/test_helper.rb +0 -57
@@ -1,372 +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
- [PR please for conditional attributes:)](https://github.com/rails-api/active_model_serializers/pull/1403)
38
-
39
- ### Associations
40
-
41
- The interface for associations is, generically:
42
-
43
- > `association_type(association_name, options, &block)`
44
-
45
- Where:
46
-
47
- - `association_type` may be `has_one`, `has_many`, `belongs_to`.
48
- - `association_name` is a method name the serializer calls.
49
- - optional: `options` may be:
50
- - `key:` The name used for the serialized association.
51
- - `serializer:`
52
- - `if:`
53
- - `unless:`
54
- - `virtual_value:`
55
- - `polymorphic:` defines if polymorphic relation type should be nested in serialized association.
56
- - optional: `&block` is a context that returns the association's attributes.
57
- - prevents `association_name` method from being called.
58
- - return value of block is used as the association value.
59
- - yields the `serializer` to the block.
60
- - `include_data false` prevents the `data` key from being rendered in the JSON API relationship.
61
-
62
- #### ::has_one
63
-
64
- e.g.
65
-
66
- ```ruby
67
- has_one :bio
68
- has_one :blog, key: :site
69
- has_one :maker, virtual_value: { id: 1 }
70
-
71
- has_one :blog do |serializer|
72
- serializer.cached_blog
73
- end
74
-
75
- def cached_blog
76
- cache_store.fetch("cached_blog:#{object.updated_at}") do
77
- Blog.find(object.blog_id)
78
- end
79
- end
80
- ```
81
-
82
- ```ruby
83
- has_one :blog, if: :show_blog?
84
- # you can also use a string or lambda
85
- # has_one :blog, if: 'scope.admin?'
86
- # has_one :blog, if: -> (serializer) { serializer.scope.admin? }
87
- # has_one :blog, if: -> { scope.admin? }
88
-
89
- def show_blog?
90
- scope.admin?
91
- end
92
- ```
93
-
94
- #### ::has_many
95
-
96
- e.g.
97
-
98
- ```ruby
99
- has_many :comments
100
- has_many :comments, key: :reviews
101
- has_many :comments, serializer: CommentPreviewSerializer
102
- has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]
103
- has_many :comments, key: :last_comments do
104
- last(1)
105
- end
106
- ```
107
-
108
- #### ::belongs_to
109
-
110
- e.g.
111
-
112
- ```ruby
113
- belongs_to :author, serializer: AuthorPreviewSerializer
114
- belongs_to :author, key: :writer
115
- belongs_to :post
116
- belongs_to :blog
117
- def blog
118
- Blog.new(id: 999, name: 'Custom blog')
119
- end
120
- ```
121
-
122
- ### Polymorphic Relationships
123
-
124
- Polymorphic relationships are serialized by specifying the relationship, like any other association. For example:
125
-
126
- ```ruby
127
- class PictureSerializer < ActiveModel::Serializer
128
- has_one :imageable
129
- end
130
- ```
131
-
132
- For more context, see the [tests](../../test/adapter/polymorphic_test.rb) for each adapter.
133
-
134
- ### Caching
135
-
136
- #### ::cache
137
-
138
- e.g.
139
-
140
- ```ruby
141
- cache key: 'post', expires_in: 0.1, skip_digest: true
142
- cache expires_in: 1.day, skip_digest: true
143
- cache key: 'writer', skip_digest: true
144
- cache only: [:name], skip_digest: true
145
- cache except: [:content], skip_digest: true
146
- cache key: 'blog'
147
- cache only: [:id]
148
- ```
149
-
150
- #### #cache_key
151
-
152
- e.g.
153
-
154
- ```ruby
155
- # Uses a custom non-time-based cache key
156
- def cache_key
157
- "#{self.class.name.downcase}/#{self.id}"
158
- end
159
- ```
160
-
161
- ### Other
162
-
163
- #### ::type
164
-
165
- The `::type` method defines the JSONAPI [type](http://jsonapi.org/format/#document-resource-object-identification) that will be rendered for this serializer.
166
- It either takes a `String` or `Symbol` as parameter.
167
-
168
- Note: This method is useful only when using the `:json_api` adapter.
169
-
170
- Examples:
171
- ```ruby
172
- class UserProfileSerializer < ActiveModel::Serializer
173
- type 'profile'
174
- end
175
- class AuthorProfileSerializer < ActiveModel::Serializer
176
- type :profile
177
- end
178
- ```
179
-
180
- With the `:json_api` adapter, the previous serializers would be rendered as:
181
-
182
- ``` json
183
- {
184
- "data": {
185
- "id": "1",
186
- "type": "profile"
187
- }
188
- }
189
- ```
190
-
191
- #### ::link
192
-
193
- ```ruby
194
- link :self do
195
- href "https://example.com/link_author/#{object.id}"
196
- end
197
- link :author { link_author_url(object) }
198
- link :link_authors { link_authors_url }
199
- link :other, 'https://example.com/resource'
200
- link :posts { link_author_posts_url(object) }
201
- ```
202
-
203
- #### #object
204
-
205
- The object being serialized.
206
-
207
- #### #root
208
-
209
- PR please :)
210
-
211
- #### #scope
212
-
213
- Allows you to include in the serializer access to an external method.
214
-
215
- It's intended to provide an authorization context to the serializer, so that
216
- you may e.g. show an admin all comments on a post, else only published comments.
217
-
218
- - `scope` is a method on the serializer instance that comes from `options[:scope]`. It may be nil.
219
- - `scope_name` is an option passed to the new serializer (`options[:scope_name]`). The serializer
220
- defines a method with that name that calls the `scope`, e.g. `def current_user; scope; end`.
221
- Note: it does not define the method if the serializer instance responds to it.
222
-
223
- That's a lot of words, so here's some examples:
224
-
225
- First, let's assume the serializer is instantiated in the controller, since that's the usual scenario.
226
- We'll refer to the serialization context as `controller`.
227
-
228
- | options | `Serializer#scope` | method definition |
229
- |-------- | ------------------|--------------------|
230
- | `scope: current_user, scope_name: :current_user` | `current_user` | `Serializer#current_user` calls `controller.current_user`
231
- | `scope: view_context, scope_name: :view_context` | `view_context` | `Serializer#view_context` calls `controller.view_context`
232
-
233
- We can take advantage of the scope to customize the objects returned based
234
- on the current user (scope).
235
-
236
- For example, we can limit the posts the current user sees to those they created:
237
-
238
- ```ruby
239
- class PostSerializer < ActiveModel::Serializer
240
- attributes :id, :title, :body
241
-
242
- # scope comments to those created_by the current user
243
- has_many :comments do
244
- object.comments.where(created_by: current_user)
245
- end
246
- end
247
- ```
248
-
249
- Whether you write the method as above or as `object.comments.where(created_by: scope)`
250
- is a matter of preference (assuming `scope_name` has been set).
251
-
252
- ##### Controller Authorization Context
253
-
254
- In the controller, the scope/scope_name options are equal to
255
- the [`serialization_scope`method](https://github.com/rails-api/active_model_serializers/blob/d02cd30fe55a3ea85e1d351b6e039620903c1871/lib/action_controller/serialization.rb#L13-L20),
256
- which is `:current_user`, by default.
257
-
258
- Specfically, the `scope_name` is defaulted to `:current_user`, and may be set as
259
- `serialization_scope :view_context`. The `scope` is set to `send(scope_name)` when `scope_name` is
260
- present and the controller responds to `scope_name`.
261
-
262
- Thus, in a serializer, the controller provides `current_user` as the
263
- current authorization scope when you call `render :json`.
264
-
265
- **IMPORTANT**: Since the scope is set at render, you may want to customize it so that `current_user` isn't
266
- called on every request. This was [also a problem](https://github.com/rails-api/active_model_serializers/pull/1252#issuecomment-159810477)
267
- in [`0.9`](https://github.com/rails-api/active_model_serializers/tree/0-9-stable#customizing-scope).
268
-
269
- We can change the scope from `current_user` to `view_context`.
270
-
271
- ```diff
272
- class SomeController < ActionController::Base
273
- + serialization_scope :view_context
274
-
275
- def current_user
276
- User.new(id: 2, name: 'Bob', admin: true)
277
- end
278
-
279
- def edit
280
- user = User.new(id: 1, name: 'Pete')
281
- render json: user, serializer: AdminUserSerializer, adapter: :json_api
282
- end
283
- end
284
- ```
285
-
286
- We could then use the controller method `view_context` in our serializer, like so:
287
-
288
- ```diff
289
- class AdminUserSerializer < ActiveModel::Serializer
290
- attributes :id, :name, :can_edit
291
-
292
- def can_edit?
293
- + view_context.current_user.admin?
294
- end
295
- end
296
- ```
297
-
298
- So that when we render the `#edit` action, we'll get
299
-
300
- ```json
301
- {"data":{"id":"1","type":"users","attributes":{"name":"Pete","can_edit":true}}}
302
- ```
303
-
304
- Where `can_edit` is `view_context.current_user.admin?` (true).
305
-
306
- #### #read_attribute_for_serialization(key)
307
-
308
- The serialized value for a given key. e.g. `read_attribute_for_serialization(:title) #=> 'Hello World'`
309
-
310
- #### #links
311
-
312
- PR please :)
313
-
314
- #### #json_key
315
-
316
- PR please :)
317
-
318
- ## Examples
319
-
320
- Given two models, a `Post(title: string, body: text)` and a
321
- `Comment(name: string, body: text, post_id: integer)`, you will have two
322
- serializers:
323
-
324
- ```ruby
325
- class PostSerializer < ActiveModel::Serializer
326
- cache key: 'posts', expires_in: 3.hours
327
- attributes :title, :body
328
-
329
- has_many :comments
330
- end
331
- ```
332
-
333
- and
334
-
335
- ```ruby
336
- class CommentSerializer < ActiveModel::Serializer
337
- attributes :name, :body
338
-
339
- belongs_to :post
340
- end
341
- ```
342
-
343
- Generally speaking, you, as a user of ActiveModelSerializers, will write (or generate) these
344
- serializer classes.
345
-
346
- ## More Info
347
-
348
- For more information, see [the Serializer class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer.rb)
349
-
350
- ## Overriding association methods
351
-
352
- To override an association, call `has_many`, `has_one` or `belongs_to` with a block:
353
-
354
- ```ruby
355
- class PostSerializer < ActiveModel::Serializer
356
- has_many :comments do
357
- object.comments.active
358
- end
359
- end
360
- ```
361
-
362
- ## Overriding attribute methods
363
-
364
- To override an attribute, call `attribute` with a block:
365
-
366
- ```ruby
367
- class PostSerializer < ActiveModel::Serializer
368
- attribute :body do
369
- object.body.downcase
370
- end
371
- end
372
- ```
Binary file
@@ -1,139 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- # How to add pagination links
4
-
5
- ### JSON API adapter
6
-
7
- Pagination links will be included in your response automatically as long as
8
- the resource is paginated and if you are using the ```JsonApi``` adapter.
9
-
10
- If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari)
11
- or [WillPaginate](https://github.com/mislav/will_paginate).
12
-
13
- Although the others adapters does not have this feature, it is possible to
14
- implement pagination links to `JSON` adapter. For more information about it,
15
- please see in our docs
16
-
17
- ###### Kaminari examples
18
-
19
- ```ruby
20
- #array
21
- @posts = Kaminari.paginate_array([1, 2, 3]).page(3).per(1)
22
- render json: @posts
23
-
24
- #active_record
25
- @posts = Post.page(3).per(1)
26
- render json: @posts
27
- ```
28
-
29
- ###### WillPaginate examples
30
-
31
- ```ruby
32
- #array
33
- @posts = [1,2,3].paginate(page: 3, per_page: 1)
34
- render json: @posts
35
-
36
- #active_record
37
- @posts = Post.page(3).per_page(1)
38
- render json: @posts
39
- ```
40
-
41
- ```ruby
42
- ActiveModelSerializers.config.adapter = :json_api
43
- ```
44
-
45
- ex:
46
- ```json
47
- {
48
- "data": [
49
- {
50
- "type": "articles",
51
- "id": "3",
52
- "attributes": {
53
- "title": "JSON API paints my bikeshed!",
54
- "body": "The shortest article. Ever.",
55
- "created": "2015-05-22T14:56:29.000Z",
56
- "updated": "2015-05-22T14:56:28.000Z"
57
- }
58
- }
59
- ],
60
- "links": {
61
- "self": "http://example.com/articles?page[number]=3&page[size]=1",
62
- "first": "http://example.com/articles?page[number]=1&page[size]=1",
63
- "prev": "http://example.com/articles?page[number]=2&page[size]=1",
64
- "next": "http://example.com/articles?page[number]=4&page[size]=1",
65
- "last": "http://example.com/articles?page[number]=13&page[size]=1"
66
- }
67
- }
68
- ```
69
-
70
- ActiveModelSerializers pagination relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
71
-
72
-
73
- ### JSON adapter
74
-
75
- If you are using `JSON` adapter, pagination links will not be included automatically, but it is possible to do so using `meta` key.
76
-
77
- Add this method to your base API controller.
78
-
79
- ```ruby
80
- def pagination_dict(object)
81
- {
82
- current_page: object.current_page,
83
- next_page: object.next_page,
84
- prev_page: object.prev_page,
85
- total_pages: object.total_pages,
86
- total_count: object.total_count
87
- }
88
- end
89
- ```
90
-
91
- Then, use it on your render method.
92
-
93
- ```ruby
94
- render json: posts, meta: pagination_dict(posts)
95
- ```
96
-
97
- ex.
98
- ```json
99
- {
100
- "posts": [
101
- {
102
- "id": 2,
103
- "title": "JSON API paints my bikeshed!",
104
- "body": "The shortest article. Ever."
105
- }
106
- ],
107
- "meta": {
108
- "current_page": 3,
109
- "next_page": 4,
110
- "prev_page": 2,
111
- "total_pages": 10,
112
- "total_count": 10
113
- }
114
- }
115
- ```
116
-
117
- You can also achieve the same result if you have a helper method that adds the pagination info in the meta tag. For instance, in your action specify a custom serializer.
118
-
119
- ```ruby
120
- render json: @posts, each_serializer: PostPreviewSerializer, meta: meta_attributes(@post)
121
- ```
122
-
123
- ```ruby
124
- #expects pagination!
125
- def meta_attributes(resource, extra_meta = {})
126
- {
127
- current_page: resource.current_page,
128
- next_page: resource.next_page,
129
- prev_page: resource.prev_page,
130
- total_pages: resource.total_pages,
131
- total_count: resource.total_count
132
- }.merge(extra_meta)
133
- end
134
- ```
135
-
136
-
137
- ### Attributes adapter
138
-
139
- This adapter does not allow us to use `meta` key, due to that it is not possible to add pagination links.
@@ -1,51 +0,0 @@
1
- # How to add root key
2
-
3
- Add the root key to your API is quite simple with ActiveModelSerializers. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```Attributes``` which doesn't have the root key, so your response is something similar to:
4
-
5
- ```json
6
- {
7
- "id": 1,
8
- "title": "Awesome Post Tile",
9
- "content": "Post content"
10
- }
11
- ```
12
-
13
- In order to add the root key you need to use the ```JSON``` Adapter, you can change this in an initializer:
14
-
15
- ```ruby
16
- ActiveModelSerializers.config.adapter = :json
17
- ```
18
-
19
- You can also specify a class as adapter, as long as it complies with the ActiveModelSerializers adapters interface.
20
- It will add the root key to all your serialized endpoints.
21
-
22
- ex:
23
-
24
- ```json
25
- {
26
- "post": {
27
- "id": 1,
28
- "title": "Awesome Post Tile",
29
- "content": "Post content"
30
- }
31
- }
32
- ```
33
-
34
- or if it returns a collection:
35
-
36
- ```json
37
- {
38
- "posts": [
39
- {
40
- "id": 1,
41
- "title": "Awesome Post Tile",
42
- "content": "Post content"
43
- },
44
- {
45
- "id": 2,
46
- "title": "Another Post Tile",
47
- "content": "Another post content"
48
- }
49
- ]
50
- }
51
- ```
@@ -1,58 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- ## Using ActiveModelSerializers Outside Of A Controller
4
-
5
- ### Serializing a resource
6
-
7
- In ActiveModelSerializers versions 0.10 or later, serializing resources outside of the controller context is fairly simple:
8
-
9
- ```ruby
10
- # Create our resource
11
- post = Post.create(title: "Sample post", body: "I love Active Model Serializers!")
12
-
13
- # Optional options parameters
14
- options = {}
15
-
16
- # Create a serializable resource instance
17
- serializable_resource = ActiveModelSerializers::SerializableResource.new(post, options)
18
-
19
- # Convert your resource into json
20
- model_json = serializable_resource.as_json
21
- ```
22
-
23
- ### Looking up the Serializer for a Resource
24
-
25
- If you want to retrieve a serializer for a specific resource, you can do the following:
26
-
27
- ```ruby
28
- # Create our resource
29
- post = Post.create(title: "Another Example", body: "So much fun.")
30
-
31
- # Optional options parameters
32
- options = {}
33
-
34
- # Retrieve the default serializer for posts
35
- serializer = ActiveModel::Serializer.serializer_for(post, options)
36
- ```
37
-
38
- You could also retrieve the serializer via:
39
-
40
- ```ruby
41
- ActiveModelSerializers::SerializableResource.new(post, options).serializer
42
- ```
43
-
44
- Both approaches will return an instance, if any, of the resource's serializer.
45
-
46
- ## Serializing before controller render
47
-
48
- At times, you might want to use a serializer without rendering it to the view. For those cases, you can create an instance of `ActiveModelSerializers::SerializableResource` with
49
- the resource you want to be serialized and call `.as_json`.
50
-
51
- ```ruby
52
- def create
53
- message = current_user.messages.create!(message_params)
54
- message_json = ActiveModelSerializers::SerializableResource.new(message).as_json
55
- MessageCreationWorker.perform(message_json)
56
- head 204
57
- end
58
- ```
@@ -1,27 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- # Passing Arbitrary Options To A Serializer
4
-
5
- In addition to the [`serialization_scope`](../general/serializers.md#scope), any options passed to `render`
6
- that are not reserved for the [adapter](../general/rendering.md#adapter_opts)
7
- are available in the serializer as [instance_options](../general/serializers.md#instance_options).
8
-
9
- For example, we could pass in a field, such as `user_id` into our serializer.
10
-
11
- ```ruby
12
- # posts_controller.rb
13
- class PostsController < ApplicationController
14
- def dashboard
15
- render json: @post, user_id: 12
16
- end
17
- end
18
-
19
- # post_serializer.rb
20
- class PostSerializer < ActiveModel::Serializer
21
- attributes :id, :title, :body
22
-
23
- def comments_by_me
24
- Comments.where(user_id: instance_options[:user_id], post_id: object.id)
25
- end
26
- end
27
- ```
@@ -1,32 +0,0 @@
1
- [Back to Guides](../README.md)
2
-
3
- # How to serialize a Plain-Old Ruby Object (PORO)
4
-
5
- When you are first getting started with ActiveModelSerializers, it may seem only `ActiveRecord::Base` objects can be serializable, but pretty much any object can be serializable with ActiveModelSerializers. Here is an example of a PORO that is serializable:
6
- ```ruby
7
- # my_model.rb
8
- class MyModel
9
- alias :read_attribute_for_serialization :send
10
- attr_accessor :id, :name, :level
11
-
12
- def initialize(attributes)
13
- @id = attributes[:id]
14
- @name = attributes[:name]
15
- @level = attributes[:level]
16
- end
17
-
18
- def self.model_name
19
- @_model_name ||= ActiveModel::Name.new(self)
20
- end
21
- end
22
- ```
23
-
24
- Fortunately, ActiveModelSerializers provides a [`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb) which you can use in production code that will make your PORO a lot cleaner. The above code now becomes:
25
- ```ruby
26
- # my_model.rb
27
- class MyModel < ActiveModelSerializers::Model
28
- attr_accessor :id, :name, :level
29
- end
30
- ```
31
-
32
- The default serializer would be `MyModelSerializer`.