active_model_serializers 0.10.0 → 0.10.7
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +6 -5
- data/.travis.yml +30 -21
- data/CHANGELOG.md +172 -2
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +23 -4
- data/README.md +166 -28
- data/Rakefile +3 -32
- data/active_model_serializers.gemspec +22 -25
- data/appveyor.yml +10 -6
- data/bin/rubocop +38 -0
- data/docs/README.md +2 -1
- data/docs/general/adapters.md +35 -11
- data/docs/general/caching.md +7 -1
- data/docs/general/configuration_options.md +86 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/fields.md +31 -0
- data/docs/general/getting_started.md +1 -1
- data/docs/general/logging.md +7 -0
- data/docs/general/rendering.md +63 -25
- data/docs/general/serializers.md +125 -14
- data/docs/howto/add_pagination_links.md +16 -17
- data/docs/howto/add_relationship_links.md +140 -0
- data/docs/howto/add_root_key.md +11 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +12 -4
- data/docs/howto/passing_arbitrary_options.md +2 -2
- data/docs/howto/serialize_poro.md +46 -5
- data/docs/howto/test.md +2 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +67 -32
- data/docs/jsonapi/schema.md +1 -1
- data/lib/action_controller/serialization.rb +13 -3
- data/lib/active_model/serializer/adapter/base.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +8 -5
- data/lib/active_model/serializer/association.rb +62 -10
- data/lib/active_model/serializer/belongs_to_reflection.rb +4 -3
- data/lib/active_model/serializer/collection_serializer.rb +39 -13
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +82 -115
- data/lib/active_model/serializer/error_serializer.rb +11 -7
- data/lib/active_model/serializer/errors_serializer.rb +25 -20
- data/lib/active_model/serializer/has_many_reflection.rb +3 -3
- data/lib/active_model/serializer/has_one_reflection.rb +1 -4
- data/lib/active_model/serializer/lazy_association.rb +95 -0
- data/lib/active_model/serializer/lint.rb +134 -130
- data/lib/active_model/serializer/reflection.rb +127 -67
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model/serializer.rb +297 -79
- data/lib/active_model_serializers/adapter/attributes.rb +3 -66
- data/lib/active_model_serializers/adapter/base.rb +39 -39
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +2 -2
- data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +47 -21
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +75 -23
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +39 -10
- data/lib/active_model_serializers/adapter/json_api.rb +71 -57
- data/lib/active_model_serializers/adapter.rb +6 -0
- data/lib/active_model_serializers/deprecate.rb +1 -2
- data/lib/active_model_serializers/deserialization.rb +2 -0
- data/lib/active_model_serializers/lookup_chain.rb +80 -0
- data/lib/active_model_serializers/model.rb +109 -28
- data/lib/active_model_serializers/railtie.rb +3 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
- data/lib/active_model_serializers/serializable_resource.rb +6 -5
- data/lib/active_model_serializers/serialization_context.rb +10 -3
- data/lib/active_model_serializers/test/schema.rb +2 -2
- data/lib/active_model_serializers.rb +16 -1
- data/lib/generators/rails/resource_override.rb +1 -1
- data/lib/generators/rails/serializer_generator.rb +4 -4
- data/lib/grape/active_model_serializers.rb +7 -5
- data/lib/grape/formatters/active_model_serializers.rb +19 -2
- data/lib/grape/helpers/active_model_serializers.rb +1 -0
- data/lib/tasks/rubocop.rake +53 -0
- data/test/action_controller/adapter_selector_test.rb +14 -5
- data/test/action_controller/explicit_serializer_test.rb +5 -4
- data/test/action_controller/json/include_test.rb +106 -27
- data/test/action_controller/json_api/deserialization_test.rb +1 -1
- data/test/action_controller/json_api/errors_test.rb +8 -9
- data/test/action_controller/json_api/fields_test.rb +66 -0
- data/test/action_controller/json_api/linked_test.rb +29 -24
- data/test/action_controller/json_api/pagination_test.rb +31 -23
- data/test/action_controller/json_api/transform_test.rb +11 -3
- data/test/action_controller/lookup_proc_test.rb +49 -0
- data/test/action_controller/namespace_lookup_test.rb +232 -0
- data/test/action_controller/serialization_scope_name_test.rb +12 -6
- data/test/action_controller/serialization_test.rb +12 -9
- data/test/active_model_serializers/json_pointer_test.rb +15 -13
- data/test/active_model_serializers/model_test.rb +137 -4
- data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
- data/test/active_model_serializers/test/schema_test.rb +3 -2
- data/test/adapter/attributes_test.rb +40 -0
- data/test/adapter/json/collection_test.rb +14 -0
- data/test/adapter/json/has_many_test.rb +10 -2
- data/test/adapter/json/transform_test.rb +15 -15
- data/test/adapter/json_api/collection_test.rb +4 -3
- data/test/adapter/json_api/errors_test.rb +17 -19
- data/test/adapter/json_api/fields_test.rb +12 -3
- data/test/adapter/json_api/has_many_test.rb +49 -20
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +213 -0
- data/test/adapter/json_api/json_api_test.rb +5 -7
- data/test/adapter/json_api/linked_test.rb +33 -12
- data/test/adapter/json_api/links_test.rb +4 -2
- data/test/adapter/json_api/pagination_links_test.rb +53 -13
- data/test/adapter/json_api/parse_test.rb +1 -1
- data/test/adapter/json_api/relationship_test.rb +309 -73
- data/test/adapter/json_api/resource_meta_test.rb +3 -3
- data/test/adapter/json_api/transform_test.rb +263 -253
- data/test/adapter/json_api/type_test.rb +168 -36
- data/test/adapter/json_test.rb +8 -7
- data/test/adapter/null_test.rb +1 -2
- data/test/adapter/polymorphic_test.rb +52 -5
- data/test/adapter_test.rb +1 -1
- data/test/benchmark/app.rb +1 -1
- data/test/benchmark/benchmarking_support.rb +1 -1
- data/test/benchmark/bm_active_record.rb +81 -0
- data/test/benchmark/bm_adapter.rb +38 -0
- data/test/benchmark/bm_caching.rb +16 -16
- data/test/benchmark/bm_lookup_chain.rb +83 -0
- data/test/benchmark/bm_transform.rb +21 -10
- data/test/benchmark/controllers.rb +16 -17
- data/test/benchmark/fixtures.rb +72 -72
- data/test/cache_test.rb +235 -69
- data/test/collection_serializer_test.rb +31 -14
- data/test/fixtures/active_record.rb +45 -10
- data/test/fixtures/poro.rb +124 -181
- data/test/generators/serializer_generator_test.rb +23 -5
- data/test/grape_test.rb +170 -56
- data/test/lint_test.rb +1 -1
- data/test/logger_test.rb +13 -11
- data/test/serializable_resource_test.rb +18 -22
- data/test/serializers/association_macros_test.rb +3 -2
- data/test/serializers/associations_test.rb +222 -49
- data/test/serializers/attribute_test.rb +5 -3
- data/test/serializers/attributes_test.rb +1 -1
- data/test/serializers/caching_configuration_test_isolated.rb +6 -6
- data/test/serializers/fieldset_test.rb +1 -1
- data/test/serializers/meta_test.rb +12 -6
- data/test/serializers/options_test.rb +17 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
- data/test/serializers/reflection_test.rb +427 -0
- data/test/serializers/root_test.rb +1 -1
- data/test/serializers/serialization_test.rb +2 -2
- data/test/serializers/serializer_for_test.rb +12 -10
- data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
- data/test/support/isolated_unit.rb +9 -4
- data/test/support/rails5_shims.rb +8 -2
- data/test/support/rails_app.rb +2 -9
- data/test/support/serialization_testing.rb +31 -5
- data/test/test_helper.rb +13 -0
- metadata +130 -71
- data/.rubocop_todo.yml +0 -167
- data/docs/ARCHITECTURE.md +0 -126
- data/lib/active_model/serializer/associations.rb +0 -100
- data/lib/active_model/serializer/attributes.rb +0 -82
- data/lib/active_model/serializer/collection_reflection.rb +0 -7
- data/lib/active_model/serializer/configuration.rb +0 -35
- data/lib/active_model/serializer/include_tree.rb +0 -111
- data/lib/active_model/serializer/links.rb +0 -35
- data/lib/active_model/serializer/meta.rb +0 -29
- data/lib/active_model/serializer/singular_reflection.rb +0 -7
- data/lib/active_model/serializer/type.rb +0 -25
- data/lib/active_model_serializers/key_transform.rb +0 -70
- data/test/active_model_serializers/key_transform_test.rb +0 -263
- data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
- data/test/adapter/json_api/relationships_test.rb +0 -199
- data/test/adapter/json_api/resource_identifier_test.rb +0 -85
- data/test/include_tree/from_include_args_test.rb +0 -26
- data/test/include_tree/from_string_test.rb +0 -94
- data/test/include_tree/include_args_to_hash_test.rb +0 -64
data/README.md
CHANGED
|
@@ -24,17 +24,6 @@
|
|
|
24
24
|
</tr>
|
|
25
25
|
</table>
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
## Documentation
|
|
29
|
-
|
|
30
|
-
- [0.10 (master) Documentation](https://github.com/rails-api/active_model_serializers/tree/master)
|
|
31
|
-
- [](http://www.rubydoc.info/github/rails-api/active_model_serializers/v0.10.0)
|
|
32
|
-
- [Guides](docs)
|
|
33
|
-
- [0.9 (0-9-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
|
|
34
|
-
- [](http://www.rubydoc.info/github/rails-api/active_model_serializers/0-9-stable)
|
|
35
|
-
- [0.8 (0-8-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
|
|
36
|
-
- [](http://www.rubydoc.info/github/rails-api/active_model_serializers/0-8-stable)
|
|
37
|
-
|
|
38
27
|
## About
|
|
39
28
|
|
|
40
29
|
ActiveModelSerializers brings convention over configuration to your JSON generation.
|
|
@@ -50,33 +39,22 @@ resource serialization. The serialization has the `#as_json`, `#to_json` and `#s
|
|
|
50
39
|
methods used by the Rails JSON Renderer. (SerializableResource actually delegates
|
|
51
40
|
these methods to the adapter.)
|
|
52
41
|
|
|
53
|
-
By default ActiveModelSerializers will use the **Attributes Adapter
|
|
42
|
+
By default ActiveModelSerializers will use the **Attributes Adapter** (no JSON root).
|
|
54
43
|
But we strongly advise you to use **JsonApi Adapter**, which
|
|
55
44
|
follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
|
|
56
45
|
Check how to change the adapter in the sections below.
|
|
57
46
|
|
|
58
|
-
## RELEASE CANDIDATE, PLEASE READ
|
|
59
|
-
|
|
60
|
-
This is the **master** branch of ActiveModelSerializers.
|
|
61
|
-
|
|
62
|
-
It will become the `0.10.0` release when it's ready. Currently this is a release candidate.
|
|
63
|
-
|
|
64
47
|
`0.10.x` is **not** backward compatible with `0.9.x` nor `0.8.x`.
|
|
65
48
|
|
|
66
|
-
`0.10.x`
|
|
49
|
+
`0.10.x` is based on the `0.8.0` code, but with a more flexible
|
|
67
50
|
architecture. We'd love your help. [Learn how you can help here.](CONTRIBUTING.md)
|
|
68
51
|
|
|
69
|
-
It is generally safe and recommended to use the master branch.
|
|
70
|
-
|
|
71
|
-
For more information, see the post '[The future of
|
|
72
|
-
AMS](https://medium.com/@joaomdmoura/the-future-of-ams-e5f9047ca7e9)'.
|
|
73
|
-
|
|
74
52
|
## Installation
|
|
75
53
|
|
|
76
54
|
Add this line to your application's Gemfile:
|
|
77
55
|
|
|
78
56
|
```
|
|
79
|
-
gem 'active_model_serializers'
|
|
57
|
+
gem 'active_model_serializers', '~> 0.10.0'
|
|
80
58
|
```
|
|
81
59
|
|
|
82
60
|
And then execute:
|
|
@@ -103,8 +81,30 @@ If you'd like to chat, we have a [community slack](http://amserializers.herokuap
|
|
|
103
81
|
|
|
104
82
|
Thanks!
|
|
105
83
|
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
If you're reading this at https://github.com/rails-api/active_model_serializers you are
|
|
87
|
+
reading documentation for our `master`, which may include features that have not
|
|
88
|
+
been released yet. Please see below for the documentation relevant to you.
|
|
89
|
+
|
|
90
|
+
- [0.10 (master) Documentation](https://github.com/rails-api/active_model_serializers/tree/master)
|
|
91
|
+
- [0.10.6 (latest release) Documentation](https://github.com/rails-api/active_model_serializers/tree/v0.10.6)
|
|
92
|
+
- [](http://www.rubydoc.info/gems/active_model_serializers/0.10.6)
|
|
93
|
+
- [Guides](docs)
|
|
94
|
+
- [0.9 (0-9-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
|
|
95
|
+
- [](http://www.rubydoc.info/github/rails-api/active_model_serializers/0-9-stable)
|
|
96
|
+
- [0.8 (0-8-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
|
|
97
|
+
- [](http://www.rubydoc.info/github/rails-api/active_model_serializers/0-8-stable)
|
|
98
|
+
|
|
99
|
+
|
|
106
100
|
## High-level behavior
|
|
107
101
|
|
|
102
|
+
Choose an adapter from [adapters](lib/active_model_serializers/adapter):
|
|
103
|
+
|
|
104
|
+
``` ruby
|
|
105
|
+
ActiveModelSerializers.config.adapter = :json_api # Default: `:attributes`
|
|
106
|
+
```
|
|
107
|
+
|
|
108
108
|
Given a [serializable model](lib/active_model/serializer/lint.rb):
|
|
109
109
|
|
|
110
110
|
```ruby
|
|
@@ -114,7 +114,7 @@ class SomeResource < ActiveRecord::Base
|
|
|
114
114
|
end
|
|
115
115
|
# or
|
|
116
116
|
class SomeResource < ActiveModelSerializers::Model
|
|
117
|
-
|
|
117
|
+
attributes :title, :body
|
|
118
118
|
end
|
|
119
119
|
```
|
|
120
120
|
|
|
@@ -160,8 +160,146 @@ serializer = SomeSerializer.new(resource, serializer_options)
|
|
|
160
160
|
serializer.attributes
|
|
161
161
|
serializer.associations
|
|
162
162
|
```
|
|
163
|
-
See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for more information.
|
|
164
163
|
|
|
165
|
-
|
|
164
|
+
## Architecture
|
|
165
|
+
|
|
166
|
+
This section focuses on architecture the 0.10.x version of ActiveModelSerializers. If you are interested in the architecture of the 0.8 or 0.9 versions,
|
|
167
|
+
please refer to the [0.8 README](https://github.com/rails-api/active_model_serializers/blob/0-8-stable/README.md) or
|
|
168
|
+
[0.9 README](https://github.com/rails-api/active_model_serializers/blob/0-9-stable/README.md).
|
|
169
|
+
|
|
170
|
+
The original design is also available [here](https://github.com/rails-api/active_model_serializers/blob/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e/README.textile).
|
|
171
|
+
|
|
172
|
+
### ActiveModel::Serializer
|
|
173
|
+
|
|
174
|
+
An **`ActiveModel::Serializer`** wraps a [serializable resource](https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/serialization.rb)
|
|
175
|
+
and exposes an `attributes` method, among a few others.
|
|
176
|
+
It allows you to specify which attributes and associations should be represented in the serializatation of the resource.
|
|
177
|
+
It requires an adapter to transform its attributes into a JSON document; it cannot be serialized itself.
|
|
178
|
+
It may be useful to think of it as a
|
|
179
|
+
[presenter](http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
|
|
180
|
+
|
|
181
|
+
#### ActiveModel::CollectionSerializer
|
|
182
|
+
|
|
183
|
+
The **`ActiveModel::CollectionSerializer`** represents a collection of resources as serializers
|
|
184
|
+
and, if there is no serializer, primitives.
|
|
185
|
+
|
|
186
|
+
### ActiveModelSerializers::Adapter::Base
|
|
187
|
+
|
|
188
|
+
The **`ActiveModelSerializers::Adapter::Base`** describes the structure of the JSON document generated from a
|
|
189
|
+
serializer. For example, the `Attributes` example represents each serializer as its
|
|
190
|
+
unmodified attributes. The `JsonApi` adapter represents the serializer as a [JSON
|
|
191
|
+
API](http://jsonapi.org/) document.
|
|
192
|
+
|
|
193
|
+
### ActiveModelSerializers::SerializableResource
|
|
194
|
+
|
|
195
|
+
The **`ActiveModelSerializers::SerializableResource`** acts to coordinate the serializer(s) and adapter
|
|
196
|
+
to an object that responds to `to_json`, and `as_json`. It is used in the controller to
|
|
197
|
+
encapsulate the serialization resource when rendered. However, it can also be used on its own
|
|
198
|
+
to serialize a resource outside of a controller, as well.
|
|
199
|
+
|
|
200
|
+
### Primitive handling
|
|
201
|
+
|
|
202
|
+
Definitions: A primitive is usually a String or Array. There is no serializer
|
|
203
|
+
defined for them; they will be serialized when the resource is converted to JSON (`as_json` or
|
|
204
|
+
`to_json`). (The below also applies for any object with no serializer.)
|
|
205
|
+
|
|
206
|
+
- ActiveModelSerializers doesn't handle primitives passed to `render json:` at all.
|
|
207
|
+
|
|
208
|
+
Internally, if no serializer can be found in the controller, the resource is not decorated by
|
|
209
|
+
ActiveModelSerializers.
|
|
210
|
+
|
|
211
|
+
- However, when a primitive value is an attribute or in a collection, it is not modified.
|
|
212
|
+
|
|
213
|
+
When serializing a collection and the collection serializer (CollectionSerializer) cannot
|
|
214
|
+
identify a serializer for a resource in its collection, it throws [`:no_serializer`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128).
|
|
215
|
+
For example, when caught by `Reflection#build_association`, and the association value is set directly:
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
(which is called by the adapter as `serializer.associations(*)`.)
|
|
222
|
+
|
|
223
|
+
### How options are parsed
|
|
224
|
+
|
|
225
|
+
High-level overview:
|
|
226
|
+
|
|
227
|
+
- For a **collection**
|
|
228
|
+
- `:serializer` specifies the collection serializer and
|
|
229
|
+
- `:each_serializer` specifies the serializer for each resource in the collection.
|
|
230
|
+
- For a **single resource**, the `:serializer` option is the resource serializer.
|
|
231
|
+
- Options are partitioned in serializer options and adapter options. Keys for adapter options are specified by
|
|
232
|
+
[`ADAPTER_OPTION_KEYS`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/serializable_resource.rb#L5).
|
|
233
|
+
The remaining options are serializer options.
|
|
234
|
+
|
|
235
|
+
Details:
|
|
236
|
+
|
|
237
|
+
1. **ActionController::Serialization**
|
|
238
|
+
1. `serializable_resource = ActiveModelSerializers::SerializableResource.new(resource, options)`
|
|
239
|
+
1. `options` are partitioned into `adapter_opts` and everything else (`serializer_opts`).
|
|
240
|
+
The `adapter_opts` keys are defined in [`ActiveModelSerializers::SerializableResource::ADAPTER_OPTION_KEYS`](lib/active_model_serializers/serializable_resource.rb#L5).
|
|
241
|
+
1. **ActiveModelSerializers::SerializableResource**
|
|
242
|
+
1. `if serializable_resource.serializer?` (there is a serializer for the resource, and an adapter is used.)
|
|
243
|
+
- Where `serializer?` is `use_adapter? && !!(serializer)`
|
|
244
|
+
- Where `use_adapter?`: 'True when no explicit adapter given, or explicit value is truthy (non-nil);
|
|
245
|
+
False when explicit adapter is falsy (nil or false)'
|
|
246
|
+
- Where `serializer`:
|
|
247
|
+
1. from explicit `:serializer` option, else
|
|
248
|
+
2. implicitly from resource `ActiveModel::Serializer.serializer_for(resource)`
|
|
249
|
+
1. A side-effect of checking `serializer` is:
|
|
250
|
+
- The `:serializer` option is removed from the serializer_opts hash
|
|
251
|
+
- If the `:each_serializer` option is present, it is removed from the serializer_opts hash and set as the `:serializer` option
|
|
252
|
+
1. The serializer and adapter are created as
|
|
253
|
+
1. `serializer_instance = serializer.new(resource, serializer_opts)`
|
|
254
|
+
2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
|
|
255
|
+
1. **ActiveModel::Serializer::CollectionSerializer#new**
|
|
256
|
+
1. If the `serializer_instance` was a `CollectionSerializer` and the `:serializer` serializer_opts
|
|
257
|
+
is present, then [that serializer is passed into each resource](https://github.com/rails-api/active_model_serializers/blob/a54d237e2828fe6bab1ea5dfe6360d4ecc8214cd/lib/active_model/serializer/array_serializer.rb#L14-L16).
|
|
258
|
+
1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
|
|
259
|
+
resource as defined by the serializer.
|
|
260
|
+
|
|
261
|
+
(In Rails, the `options` are also passed to the `as_json(options)` or `to_json(options)`
|
|
262
|
+
methods on the resource serialization by the Rails JSON renderer. They are, therefore, important
|
|
263
|
+
to know about, but not part of ActiveModelSerializers.)
|
|
264
|
+
|
|
265
|
+
### What does a 'serializable resource' look like?
|
|
266
|
+
|
|
267
|
+
- An `ActiveRecord::Base` object.
|
|
268
|
+
- Any Ruby object that passes the
|
|
269
|
+
[Lint](http://www.rubydoc.info/github/rails-api/active_model_serializers/ActiveModel/Serializer/Lint/Tests)
|
|
270
|
+
[code](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer/lint.rb).
|
|
271
|
+
|
|
272
|
+
ActiveModelSerializers provides a
|
|
273
|
+
[`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb),
|
|
274
|
+
which is a simple serializable PORO (Plain-Old Ruby Object).
|
|
275
|
+
|
|
276
|
+
`ActiveModelSerializers::Model` may be used either as a reference implementation, or in production code.
|
|
277
|
+
|
|
278
|
+
```ruby
|
|
279
|
+
class MyModel < ActiveModelSerializers::Model
|
|
280
|
+
attributes :id, :name, :level
|
|
281
|
+
end
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The default serializer for `MyModel` would be `MyModelSerializer` whether MyModel is an
|
|
285
|
+
ActiveRecord::Base object or not.
|
|
286
|
+
|
|
287
|
+
Outside of the controller the rules are **exactly** the same as for records. For example:
|
|
288
|
+
|
|
289
|
+
```ruby
|
|
290
|
+
render json: MyModel.new(level: 'awesome'), adapter: :json
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
would be serialized the same as
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
ActiveModelSerializers::SerializableResource.new(MyModel.new(level: 'awesome'), adapter: :json).as_json
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Semantic Versioning
|
|
300
|
+
|
|
301
|
+
This project adheres to [semver](http://semver.org/)
|
|
302
|
+
|
|
303
|
+
## Contributing
|
|
166
304
|
|
|
167
305
|
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
data/Rakefile
CHANGED
|
@@ -5,8 +5,9 @@ rescue LoadError
|
|
|
5
5
|
end
|
|
6
6
|
begin
|
|
7
7
|
require 'simplecov'
|
|
8
|
-
rescue LoadError
|
|
8
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
9
9
|
end
|
|
10
|
+
import('lib/tasks/rubocop.rake')
|
|
10
11
|
|
|
11
12
|
Bundler::GemHelper.install_tasks
|
|
12
13
|
|
|
@@ -30,36 +31,6 @@ namespace :yard do
|
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
begin
|
|
34
|
-
require 'rubocop'
|
|
35
|
-
require 'rubocop/rake_task'
|
|
36
|
-
rescue LoadError
|
|
37
|
-
else
|
|
38
|
-
Rake::Task[:rubocop].clear if Rake::Task.task_defined?(:rubocop)
|
|
39
|
-
require 'rbconfig'
|
|
40
|
-
# https://github.com/bundler/bundler/blob/1b3eb2465a/lib/bundler/constants.rb#L2
|
|
41
|
-
windows_platforms = /(msdos|mswin|djgpp|mingw)/
|
|
42
|
-
if RbConfig::CONFIG['host_os'] =~ windows_platforms
|
|
43
|
-
desc 'No-op rubocop on Windows-- unsupported platform'
|
|
44
|
-
task :rubocop do
|
|
45
|
-
puts 'Skipping rubocop on Windows'
|
|
46
|
-
end
|
|
47
|
-
elsif defined?(::Rubinius)
|
|
48
|
-
desc 'No-op rubocop to avoid rbx segfault'
|
|
49
|
-
task :rubocop do
|
|
50
|
-
puts 'Skipping rubocop on rbx due to segfault'
|
|
51
|
-
puts 'https://github.com/rubinius/rubinius/issues/3499'
|
|
52
|
-
end
|
|
53
|
-
else
|
|
54
|
-
Rake::Task[:rubocop].clear if Rake::Task.task_defined?(:rubocop)
|
|
55
|
-
desc 'Execute rubocop'
|
|
56
|
-
RuboCop::RakeTask.new(:rubocop) do |task|
|
|
57
|
-
task.options = ['--rails', '--display-cop-names', '--display-style-guide']
|
|
58
|
-
task.fail_on_error = true
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
34
|
require 'rake/testtask'
|
|
64
35
|
|
|
65
36
|
Rake::TestTask.new(:test) do |t|
|
|
@@ -100,4 +71,4 @@ else
|
|
|
100
71
|
end
|
|
101
72
|
|
|
102
73
|
desc 'CI test task'
|
|
103
|
-
task :
|
|
74
|
+
task ci: [:default]
|
|
@@ -19,33 +19,36 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.require_paths = ['lib']
|
|
20
20
|
spec.executables = []
|
|
21
21
|
|
|
22
|
-
spec.required_ruby_version = '>= 2.
|
|
22
|
+
spec.required_ruby_version = '>= 2.1'
|
|
23
23
|
|
|
24
|
-
rails_versions = '>= 4.
|
|
24
|
+
rails_versions = ['>= 4.1', '< 6']
|
|
25
25
|
spec.add_runtime_dependency 'activemodel', rails_versions
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
# 'activesupport', rails_versions
|
|
27
|
+
# 'builder'
|
|
28
28
|
|
|
29
29
|
spec.add_runtime_dependency 'actionpack', rails_versions
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
# 'activesupport', rails_versions
|
|
31
|
+
# 'rack'
|
|
32
|
+
# 'rack-test', '~> 0.6.2'
|
|
33
33
|
|
|
34
|
-
spec.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
spec.add_development_dependency 'railties', rails_versions
|
|
35
|
+
# 'activesupport', rails_versions
|
|
36
|
+
# 'actionpack', rails_versions
|
|
37
|
+
# 'rake', '>= 0.8.7'
|
|
38
38
|
|
|
39
39
|
# 'activesupport', rails_versions
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
# 'i18n,
|
|
41
|
+
# 'tzinfo'
|
|
42
|
+
# 'minitest'
|
|
43
|
+
# 'thread_safe'
|
|
44
|
+
|
|
45
|
+
spec.add_runtime_dependency 'jsonapi-renderer', ['>= 0.1.1.beta1', '< 0.3']
|
|
46
|
+
spec.add_runtime_dependency 'case_transform', '>= 0.2'
|
|
44
47
|
|
|
45
48
|
spec.add_development_dependency 'activerecord', rails_versions
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
# arel
|
|
50
|
+
# activesupport
|
|
51
|
+
# activemodel
|
|
49
52
|
|
|
50
53
|
# Soft dependency for pagination
|
|
51
54
|
spec.add_development_dependency 'kaminari', ' ~> 0.16.3'
|
|
@@ -54,13 +57,7 @@ Gem::Specification.new do |spec|
|
|
|
54
57
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
|
55
58
|
spec.add_development_dependency 'simplecov', '~> 0.11'
|
|
56
59
|
spec.add_development_dependency 'timecop', '~> 0.7'
|
|
57
|
-
spec.add_development_dependency 'grape', ['>= 0.13', '< 1
|
|
60
|
+
spec.add_development_dependency 'grape', ['>= 0.13', '< 0.19.1']
|
|
58
61
|
spec.add_development_dependency 'json_schema'
|
|
59
62
|
spec.add_development_dependency 'rake', ['>= 10.0', '< 12.0']
|
|
60
|
-
|
|
61
|
-
spec.post_install_message = <<-EOF
|
|
62
|
-
NOTE: The default key case for the JsonApi adapter has changed to dashed.
|
|
63
|
-
See https://github.com/rails-api/active_model_serializers/blob/master/docs/general/key_transforms.md
|
|
64
|
-
for more information on configuring this behavior.
|
|
65
|
-
EOF
|
|
66
63
|
end
|
data/appveyor.yml
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
version:
|
|
1
|
+
version: 1.0.{build}-{branch}
|
|
2
2
|
|
|
3
3
|
skip_tags: true
|
|
4
4
|
|
|
5
5
|
environment:
|
|
6
6
|
JRUBY_OPTS: "--dev -J-Xmx1024M --debug"
|
|
7
7
|
matrix:
|
|
8
|
-
- ruby_version: "
|
|
9
|
-
- ruby_version: "
|
|
10
|
-
- ruby_version: "jruby-9.0.0.0"
|
|
8
|
+
- ruby_version: "Ruby23"
|
|
9
|
+
- ruby_version: "Ruby23-x64"
|
|
11
10
|
|
|
12
11
|
cache:
|
|
13
12
|
- vendor/bundle
|
|
14
13
|
|
|
15
14
|
install:
|
|
16
15
|
- SET PATH=C:\%ruby_version%\bin;%PATH%
|
|
17
|
-
- gem install bundler
|
|
18
16
|
- bundle env
|
|
19
|
-
- bundle install --path=vendor/bundle --retry=3 --jobs=3
|
|
17
|
+
- bundle check || bundle install --path=vendor/bundle --retry=3 --jobs=3
|
|
18
|
+
- bundle clean --force
|
|
19
|
+
|
|
20
|
+
before_test:
|
|
21
|
+
- ruby -v
|
|
22
|
+
- gem -v
|
|
23
|
+
- bundle -v
|
|
20
24
|
|
|
21
25
|
test_script:
|
|
22
26
|
- bundle exec rake ci
|
data/bin/rubocop
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Usage:
|
|
4
|
+
# bin/rubocop [-A|-t|-h]
|
|
5
|
+
# bin/rubocop [file or path] [cli options]
|
|
6
|
+
#
|
|
7
|
+
# Options:
|
|
8
|
+
# Autocorrect -A
|
|
9
|
+
# AutoGenConfig -t
|
|
10
|
+
# Usage -h,--help,help
|
|
11
|
+
|
|
12
|
+
set -e
|
|
13
|
+
|
|
14
|
+
case $1 in
|
|
15
|
+
-A)
|
|
16
|
+
echo "Rubocop autocorrect is ON" >&2
|
|
17
|
+
bundle exec rake -f lib/tasks/rubocop.rake rubocop:auto_correct
|
|
18
|
+
;;
|
|
19
|
+
|
|
20
|
+
-t)
|
|
21
|
+
echo "Rubocop is generating a new TODO" >&2
|
|
22
|
+
bundle exec rake -f lib/tasks/rubocop.rake rubocop:auto_gen_config
|
|
23
|
+
;;
|
|
24
|
+
|
|
25
|
+
-h|--help|help)
|
|
26
|
+
sed -ne '/^#/!q;s/.\{1,2\}//;1d;p' < "$0"
|
|
27
|
+
;;
|
|
28
|
+
|
|
29
|
+
*)
|
|
30
|
+
# with no args, run vanilla rubocop
|
|
31
|
+
# else assume we're passing in arbitrary arguments
|
|
32
|
+
if [ -z "$1" ]; then
|
|
33
|
+
bundle exec rake -f lib/tasks/rubocop.rake rubocop
|
|
34
|
+
else
|
|
35
|
+
bundle exec rubocop "$@"
|
|
36
|
+
fi
|
|
37
|
+
;;
|
|
38
|
+
esac
|
data/docs/README.md
CHANGED
|
@@ -18,16 +18,17 @@ This is the documentation of ActiveModelSerializers, it's focused on the **0.10.
|
|
|
18
18
|
- JSON API
|
|
19
19
|
- [Schema](jsonapi/schema.md)
|
|
20
20
|
- [Errors](jsonapi/errors.md)
|
|
21
|
-
- [ARCHITECTURE](ARCHITECTURE.md)
|
|
22
21
|
|
|
23
22
|
## How to
|
|
24
23
|
|
|
25
24
|
- [How to add root key](howto/add_root_key.md)
|
|
26
25
|
- [How to add pagination links](howto/add_pagination_links.md)
|
|
26
|
+
- [How to add relationship links](howto/add_relationship_links.md)
|
|
27
27
|
- [Using ActiveModelSerializers Outside Of Controllers](howto/outside_controller_use.md)
|
|
28
28
|
- [Testing ActiveModelSerializers](howto/test.md)
|
|
29
29
|
- [Passing Arbitrary Options](howto/passing_arbitrary_options.md)
|
|
30
30
|
- [How to serialize a Plain-Old Ruby Object (PORO)](howto/serialize_poro.md)
|
|
31
|
+
- [How to upgrade from `0.8` to `0.10` safely](howto/upgrade_from_0_8_to_0_10.md)
|
|
31
32
|
|
|
32
33
|
## Integrations
|
|
33
34
|
|
data/docs/general/adapters.md
CHANGED
|
@@ -36,6 +36,12 @@ The `Attributes` adapter does not include a root key. It is just the serialized
|
|
|
36
36
|
|
|
37
37
|
Use either the `JSON` or `JSON API` adapters if you want the response document to have a root key.
|
|
38
38
|
|
|
39
|
+
***IMPORTANT***: Adapter configuration has *no effect* on a serializer instance
|
|
40
|
+
being used directly. That is, `UserSerializer.new(user).as_json` will *always*
|
|
41
|
+
behave as if the adapter were the 'Attributes' adapter. See [Outside Controller
|
|
42
|
+
Usage](../howto/outside_controller_use.md) for more details on recommended
|
|
43
|
+
usage.
|
|
44
|
+
|
|
39
45
|
## Built in Adapters
|
|
40
46
|
|
|
41
47
|
### Attributes - Default
|
|
@@ -67,9 +73,11 @@ Doesn't follow any specific convention.
|
|
|
67
73
|
|
|
68
74
|
### JSON
|
|
69
75
|
|
|
70
|
-
The response
|
|
76
|
+
The json response is always rendered with a root key.
|
|
71
77
|
|
|
72
|
-
The root key
|
|
78
|
+
The root key can be overridden by:
|
|
79
|
+
* passing the `root` option in the render call. See details in the [Rendering Guides](rendering.md#overriding-the-root-key).
|
|
80
|
+
* setting the `type` of the serializer. See details in the [Serializers Guide](serializers.md#type).
|
|
73
81
|
|
|
74
82
|
Doesn't follow any specific convention.
|
|
75
83
|
|
|
@@ -139,18 +147,25 @@ This adapter follows **version 1.0** of the [format specified](../jsonapi/schema
|
|
|
139
147
|
}
|
|
140
148
|
```
|
|
141
149
|
|
|
142
|
-
|
|
150
|
+
### Include option
|
|
143
151
|
|
|
144
|
-
|
|
145
|
-
when the resource names are included in the `include` option.
|
|
146
|
-
Including nested associated resources is also supported.
|
|
152
|
+
Which [serializer associations](https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#associations) are rendered can be specified using the `include` option. The option usage is consistent with [the include option in the JSON API spec](http://jsonapi.org/format/#fetching-includes), and is available in all adapters.
|
|
147
153
|
|
|
154
|
+
Example of the usage:
|
|
148
155
|
```ruby
|
|
149
156
|
render json: @posts, include: ['author', 'comments', 'comments.author']
|
|
150
157
|
# or
|
|
151
158
|
render json: @posts, include: 'author,comments,comments.author'
|
|
152
159
|
```
|
|
153
160
|
|
|
161
|
+
The format of the `include` option can be either:
|
|
162
|
+
|
|
163
|
+
- a String composed of a comma-separated list of [relationship paths](http://jsonapi.org/format/#fetching-includes).
|
|
164
|
+
- an Array of Symbols and Hashes.
|
|
165
|
+
- a mix of both.
|
|
166
|
+
|
|
167
|
+
An empty string or an empty array will prevent rendering of any associations.
|
|
168
|
+
|
|
154
169
|
In addition, two types of wildcards may be used:
|
|
155
170
|
|
|
156
171
|
- `*` includes one level of associations.
|
|
@@ -162,11 +177,6 @@ These can be combined with other paths.
|
|
|
162
177
|
render json: @posts, include: '**' # or '*' for a single layer
|
|
163
178
|
```
|
|
164
179
|
|
|
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
180
|
|
|
171
181
|
The following would render posts and include:
|
|
172
182
|
|
|
@@ -180,6 +190,20 @@ It could be combined, like above, with other paths in any combination desired.
|
|
|
180
190
|
render json: @posts, include: 'author.comments.**'
|
|
181
191
|
```
|
|
182
192
|
|
|
193
|
+
**Note:** Wildcards are ActiveModelSerializers-specific, they are not part of the JSON API spec.
|
|
194
|
+
|
|
195
|
+
The default include for the JSON API adapter is no associations. The default for the JSON and Attributes adapters is all associations.
|
|
196
|
+
|
|
197
|
+
For the JSON API adapter associated resources will be gathered in the `"included"` member. For the JSON and Attributes
|
|
198
|
+
adapters associated resources will be rendered among the other attributes.
|
|
199
|
+
|
|
200
|
+
Only for the JSON API adapter you can specify, which attributes of associated resources will be rendered. This feature
|
|
201
|
+
is called [sparse fieldset](http://jsonapi.org/format/#fetching-sparse-fieldsets):
|
|
202
|
+
|
|
203
|
+
```ruby
|
|
204
|
+
render json: @posts, include: 'comments', fields: { comments: ['content', 'created_at'] }
|
|
205
|
+
```
|
|
206
|
+
|
|
183
207
|
##### Security Considerations
|
|
184
208
|
|
|
185
209
|
Since the included options may come from the query params (i.e. user-controller):
|
data/docs/general/caching.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
# Caching
|
|
4
4
|
|
|
5
|
+
## Warning
|
|
6
|
+
|
|
7
|
+
There is currently a problem with caching in AMS [Caching doesn't improve performance](https://github.com/rails-api/active_model_serializers/issues/1586). Adding caching _may_ slow down your application, rather than speeding it up. We suggest you benchmark any caching you implement before using in a production enviroment
|
|
8
|
+
|
|
9
|
+
___
|
|
10
|
+
|
|
5
11
|
To cache a serializer, call ```cache``` and pass its options.
|
|
6
12
|
The options are the same options of ```ActiveSupport::Cache::Store```, plus
|
|
7
13
|
a ```key``` option that will be the prefix of the object cache
|
|
@@ -17,7 +23,7 @@ The cache support is optimized to use the cached object in multiple request. An
|
|
|
17
23
|
cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
|
|
18
24
|
```
|
|
19
25
|
|
|
20
|
-
Take the example
|
|
26
|
+
Take the example below:
|
|
21
27
|
|
|
22
28
|
```ruby
|
|
23
29
|
class PostSerializer < ActiveModel::Serializer
|