active_model_serializers_custom 0.10.90
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 +7 -0
- data/.github/ISSUE_TEMPLATE.md +29 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- data/.gitignore +35 -0
- data/.rubocop.yml +109 -0
- data/.simplecov +110 -0
- data/.travis.yml +63 -0
- data/CHANGELOG.md +727 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +105 -0
- data/Gemfile +74 -0
- data/MIT-LICENSE +22 -0
- data/README.md +305 -0
- data/Rakefile +76 -0
- data/active_model_serializers.gemspec +64 -0
- data/appveyor.yml +28 -0
- data/bin/bench +171 -0
- data/bin/bench_regression +316 -0
- data/bin/rubocop +38 -0
- data/bin/serve_benchmark +39 -0
- data/docs/README.md +41 -0
- data/docs/STYLE.md +58 -0
- data/docs/general/adapters.md +269 -0
- data/docs/general/caching.md +58 -0
- data/docs/general/configuration_options.md +185 -0
- data/docs/general/deserialization.md +100 -0
- data/docs/general/fields.md +31 -0
- data/docs/general/getting_started.md +133 -0
- data/docs/general/instrumentation.md +40 -0
- data/docs/general/key_transforms.md +40 -0
- data/docs/general/logging.md +21 -0
- data/docs/general/rendering.md +293 -0
- data/docs/general/serializers.md +495 -0
- data/docs/how-open-source-maintained.jpg +0 -0
- data/docs/howto/add_pagination_links.md +138 -0
- data/docs/howto/add_relationship_links.md +140 -0
- data/docs/howto/add_root_key.md +62 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +66 -0
- data/docs/howto/passing_arbitrary_options.md +27 -0
- data/docs/howto/serialize_poro.md +73 -0
- data/docs/howto/test.md +154 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +147 -0
- data/docs/integrations/grape.md +19 -0
- data/docs/jsonapi/errors.md +56 -0
- data/docs/jsonapi/schema.md +151 -0
- data/docs/jsonapi/schema/schema.json +366 -0
- data/docs/rfcs/0000-namespace.md +106 -0
- data/docs/rfcs/template.md +15 -0
- data/lib/action_controller/serialization.rb +76 -0
- data/lib/active_model/serializable_resource.rb +13 -0
- data/lib/active_model/serializer.rb +418 -0
- data/lib/active_model/serializer/adapter.rb +26 -0
- data/lib/active_model/serializer/adapter/attributes.rb +17 -0
- data/lib/active_model/serializer/adapter/base.rb +20 -0
- data/lib/active_model/serializer/adapter/json.rb +17 -0
- data/lib/active_model/serializer/adapter/json_api.rb +17 -0
- data/lib/active_model/serializer/adapter/null.rb +17 -0
- data/lib/active_model/serializer/array_serializer.rb +14 -0
- data/lib/active_model/serializer/association.rb +91 -0
- data/lib/active_model/serializer/attribute.rb +27 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +13 -0
- data/lib/active_model/serializer/collection_serializer.rb +90 -0
- data/lib/active_model/serializer/concerns/caching.rb +304 -0
- data/lib/active_model/serializer/error_serializer.rb +16 -0
- data/lib/active_model/serializer/errors_serializer.rb +34 -0
- data/lib/active_model/serializer/field.rb +92 -0
- data/lib/active_model/serializer/fieldset.rb +33 -0
- data/lib/active_model/serializer/has_many_reflection.rb +12 -0
- data/lib/active_model/serializer/has_one_reflection.rb +9 -0
- data/lib/active_model/serializer/lazy_association.rb +99 -0
- data/lib/active_model/serializer/link.rb +23 -0
- data/lib/active_model/serializer/lint.rb +152 -0
- data/lib/active_model/serializer/null.rb +19 -0
- data/lib/active_model/serializer/reflection.rb +212 -0
- data/lib/active_model/serializer/version.rb +7 -0
- data/lib/active_model_serializers.rb +63 -0
- data/lib/active_model_serializers/adapter.rb +100 -0
- data/lib/active_model_serializers/adapter/attributes.rb +15 -0
- data/lib/active_model_serializers/adapter/base.rb +85 -0
- data/lib/active_model_serializers/adapter/json.rb +23 -0
- data/lib/active_model_serializers/adapter/json_api.rb +535 -0
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +215 -0
- data/lib/active_model_serializers/adapter/json_api/error.rb +98 -0
- data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +51 -0
- data/lib/active_model_serializers/adapter/json_api/link.rb +85 -0
- data/lib/active_model_serializers/adapter/json_api/meta.rb +39 -0
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +90 -0
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +106 -0
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +68 -0
- data/lib/active_model_serializers/adapter/null.rb +11 -0
- data/lib/active_model_serializers/callbacks.rb +57 -0
- data/lib/active_model_serializers/deprecate.rb +56 -0
- data/lib/active_model_serializers/deserialization.rb +17 -0
- data/lib/active_model_serializers/json_pointer.rb +16 -0
- data/lib/active_model_serializers/logging.rb +124 -0
- data/lib/active_model_serializers/lookup_chain.rb +82 -0
- data/lib/active_model_serializers/model.rb +132 -0
- data/lib/active_model_serializers/railtie.rb +52 -0
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +80 -0
- data/lib/active_model_serializers/serializable_resource.rb +84 -0
- data/lib/active_model_serializers/serialization_context.rb +41 -0
- data/lib/active_model_serializers/test.rb +9 -0
- data/lib/active_model_serializers/test/schema.rb +140 -0
- data/lib/active_model_serializers/test/serializer.rb +127 -0
- data/lib/generators/rails/USAGE +6 -0
- data/lib/generators/rails/resource_override.rb +12 -0
- data/lib/generators/rails/serializer_generator.rb +38 -0
- data/lib/generators/rails/templates/serializer.rb.erb +8 -0
- data/lib/grape/active_model_serializers.rb +18 -0
- data/lib/grape/formatters/active_model_serializers.rb +34 -0
- data/lib/grape/helpers/active_model_serializers.rb +19 -0
- data/lib/tasks/rubocop.rake +55 -0
- data/test/action_controller/adapter_selector_test.rb +64 -0
- data/test/action_controller/explicit_serializer_test.rb +137 -0
- data/test/action_controller/json/include_test.rb +248 -0
- data/test/action_controller/json_api/deserialization_test.rb +114 -0
- data/test/action_controller/json_api/errors_test.rb +42 -0
- data/test/action_controller/json_api/fields_test.rb +68 -0
- data/test/action_controller/json_api/linked_test.rb +204 -0
- data/test/action_controller/json_api/pagination_test.rb +126 -0
- data/test/action_controller/json_api/transform_test.rb +191 -0
- data/test/action_controller/lookup_proc_test.rb +51 -0
- data/test/action_controller/namespace_lookup_test.rb +239 -0
- data/test/action_controller/serialization_scope_name_test.rb +237 -0
- data/test/action_controller/serialization_test.rb +480 -0
- data/test/active_model_serializers/adapter_for_test.rb +210 -0
- data/test/active_model_serializers/json_pointer_test.rb +24 -0
- data/test/active_model_serializers/logging_test.rb +79 -0
- data/test/active_model_serializers/model_test.rb +144 -0
- data/test/active_model_serializers/railtie_test_isolated.rb +70 -0
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +73 -0
- data/test/active_model_serializers/test/schema_test.rb +133 -0
- data/test/active_model_serializers/test/serializer_test.rb +64 -0
- data/test/active_record_test.rb +11 -0
- data/test/adapter/attributes_test.rb +42 -0
- data/test/adapter/deprecation_test.rb +102 -0
- data/test/adapter/json/belongs_to_test.rb +47 -0
- data/test/adapter/json/collection_test.rb +106 -0
- data/test/adapter/json/has_many_test.rb +55 -0
- data/test/adapter/json/transform_test.rb +95 -0
- data/test/adapter/json_api/belongs_to_test.rb +157 -0
- data/test/adapter/json_api/collection_test.rb +98 -0
- data/test/adapter/json_api/errors_test.rb +78 -0
- data/test/adapter/json_api/fields_test.rb +98 -0
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
- data/test/adapter/json_api/has_many_test.rb +175 -0
- data/test/adapter/json_api/has_one_test.rb +82 -0
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
- data/test/adapter/json_api/json_api_test.rb +35 -0
- data/test/adapter/json_api/linked_test.rb +415 -0
- data/test/adapter/json_api/links_test.rb +112 -0
- data/test/adapter/json_api/pagination_links_test.rb +208 -0
- data/test/adapter/json_api/parse_test.rb +139 -0
- data/test/adapter/json_api/relationship_test.rb +399 -0
- data/test/adapter/json_api/resource_meta_test.rb +102 -0
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +84 -0
- data/test/adapter/json_api/transform_test.rb +514 -0
- data/test/adapter/json_api/type_test.rb +195 -0
- data/test/adapter/json_test.rb +48 -0
- data/test/adapter/null_test.rb +24 -0
- data/test/adapter/polymorphic_test.rb +220 -0
- data/test/adapter_test.rb +69 -0
- data/test/array_serializer_test.rb +24 -0
- data/test/benchmark/app.rb +67 -0
- data/test/benchmark/benchmarking_support.rb +69 -0
- data/test/benchmark/bm_active_record.rb +83 -0
- data/test/benchmark/bm_adapter.rb +40 -0
- data/test/benchmark/bm_caching.rb +121 -0
- data/test/benchmark/bm_lookup_chain.rb +85 -0
- data/test/benchmark/bm_transform.rb +47 -0
- data/test/benchmark/config.ru +3 -0
- data/test/benchmark/controllers.rb +85 -0
- data/test/benchmark/fixtures.rb +221 -0
- data/test/cache_test.rb +717 -0
- data/test/collection_serializer_test.rb +129 -0
- data/test/fixtures/active_record.rb +115 -0
- data/test/fixtures/poro.rb +227 -0
- data/test/generators/scaffold_controller_generator_test.rb +26 -0
- data/test/generators/serializer_generator_test.rb +77 -0
- data/test/grape_test.rb +198 -0
- data/test/lint_test.rb +51 -0
- data/test/logger_test.rb +22 -0
- data/test/poro_test.rb +11 -0
- data/test/serializable_resource_test.rb +81 -0
- data/test/serializers/association_macros_test.rb +39 -0
- data/test/serializers/associations_test.rb +520 -0
- data/test/serializers/attribute_test.rb +155 -0
- data/test/serializers/attributes_test.rb +54 -0
- data/test/serializers/caching_configuration_test_isolated.rb +172 -0
- data/test/serializers/configuration_test.rb +34 -0
- data/test/serializers/fieldset_test.rb +16 -0
- data/test/serializers/meta_test.rb +204 -0
- data/test/serializers/options_test.rb +34 -0
- data/test/serializers/read_attribute_for_serialization_test.rb +81 -0
- data/test/serializers/reflection_test.rb +481 -0
- data/test/serializers/root_test.rb +23 -0
- data/test/serializers/serialization_test.rb +57 -0
- data/test/serializers/serializer_for_test.rb +138 -0
- data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
- data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
- data/test/support/isolated_unit.rb +86 -0
- data/test/support/rails5_shims.rb +55 -0
- data/test/support/rails_app.rb +40 -0
- data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
- data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
- data/test/support/schemas/custom/show.json +7 -0
- data/test/support/schemas/hyper_schema.json +93 -0
- data/test/support/schemas/render_using_json_api.json +43 -0
- data/test/support/schemas/simple_json_pointers.json +10 -0
- data/test/support/serialization_testing.rb +81 -0
- data/test/test_helper.rb +72 -0
- metadata +622 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Caching
|
|
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
|
+
|
|
11
|
+
To cache a serializer, call ```cache``` and pass its options.
|
|
12
|
+
The options are the same options of ```ActiveSupport::Cache::Store```, plus
|
|
13
|
+
a ```key``` option that will be the prefix of the object cache
|
|
14
|
+
on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
|
|
15
|
+
|
|
16
|
+
The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
|
|
17
|
+
|
|
18
|
+
**[NOTE] Every object is individually cached.**
|
|
19
|
+
|
|
20
|
+
**[NOTE] The cache is automatically expired after an object is updated, but it's not deleted.**
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Take the example below:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
class PostSerializer < ActiveModel::Serializer
|
|
30
|
+
cache key: 'post', expires_in: 3.hours
|
|
31
|
+
attributes :title, :body
|
|
32
|
+
|
|
33
|
+
has_many :comments
|
|
34
|
+
end
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
On this example every ```Post``` object will be cached with
|
|
38
|
+
the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
|
|
39
|
+
but in this case it will be automatically expired after 3 hours.
|
|
40
|
+
|
|
41
|
+
## Fragment Caching
|
|
42
|
+
|
|
43
|
+
If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
|
|
44
|
+
|
|
45
|
+
You can define the attribute by using ```only``` or ```except``` option on cache method.
|
|
46
|
+
|
|
47
|
+
**[NOTE] Cache serializers will be used at their relationships**
|
|
48
|
+
|
|
49
|
+
Example:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
class PostSerializer < ActiveModel::Serializer
|
|
53
|
+
cache key: 'post', expires_in: 3.hours, only: [:title]
|
|
54
|
+
attributes :title, :body
|
|
55
|
+
|
|
56
|
+
has_many :comments
|
|
57
|
+
end
|
|
58
|
+
```
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Configuration Options
|
|
4
|
+
|
|
5
|
+
The following configuration options can be set on
|
|
6
|
+
`ActiveModelSerializers.config`, preferably inside an initializer.
|
|
7
|
+
|
|
8
|
+
## General
|
|
9
|
+
|
|
10
|
+
##### adapter
|
|
11
|
+
|
|
12
|
+
The [adapter](adapters.md) to use.
|
|
13
|
+
|
|
14
|
+
Possible values:
|
|
15
|
+
|
|
16
|
+
- `:attributes` (default)
|
|
17
|
+
- `:json`
|
|
18
|
+
- `:json_api`
|
|
19
|
+
|
|
20
|
+
##### serializer_lookup_enabled
|
|
21
|
+
|
|
22
|
+
Enable automatic serializer lookup.
|
|
23
|
+
|
|
24
|
+
Possible values:
|
|
25
|
+
|
|
26
|
+
- `true` (default)
|
|
27
|
+
- `false`
|
|
28
|
+
|
|
29
|
+
When `false`, serializers must be explicitly specified.
|
|
30
|
+
|
|
31
|
+
##### key_transform
|
|
32
|
+
|
|
33
|
+
The [key transform](key_transforms.md) to use.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
| Option | Result |
|
|
37
|
+
|----|----|
|
|
38
|
+
| `:camel` | ExampleKey |
|
|
39
|
+
| `:camel_lower` | exampleKey |
|
|
40
|
+
| `:dash` | example-key |
|
|
41
|
+
| `:unaltered` | the original, unaltered key |
|
|
42
|
+
| `:underscore` | example_key |
|
|
43
|
+
| `nil` | use the adapter default |
|
|
44
|
+
|
|
45
|
+
Each adapter has a default key transform configured:
|
|
46
|
+
|
|
47
|
+
| Adapter | Default Key Transform |
|
|
48
|
+
|----|----|
|
|
49
|
+
| `Attributes` | `:unaltered` |
|
|
50
|
+
| `Json` | `:unaltered` |
|
|
51
|
+
| `JsonApi` | `:dash` |
|
|
52
|
+
|
|
53
|
+
`config.key_transform` is a global override of the adapter default. Adapters
|
|
54
|
+
still prefer the render option `:key_transform` over this setting.
|
|
55
|
+
|
|
56
|
+
*NOTE: Key transforms can be expensive operations. If key transforms are unnecessary for the
|
|
57
|
+
application, setting `config.key_transform` to `:unaltered` will provide a performance boost.*
|
|
58
|
+
|
|
59
|
+
##### default_includes
|
|
60
|
+
|
|
61
|
+
What relationships to serialize by default. Default: `'*'`, which includes one level of related
|
|
62
|
+
objects. See [includes](adapters.md#included) for more info.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
##### serializer_lookup_chain
|
|
66
|
+
|
|
67
|
+
Configures how serializers are searched for. By default, the lookup chain is
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
ActiveModelSerializers::LookupChain::DEFAULT
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
which is shorthand for
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
[
|
|
77
|
+
ActiveModelSerializers::LookupChain::BY_PARENT_SERIALIZER,
|
|
78
|
+
ActiveModelSerializers::LookupChain::BY_NAMESPACE,
|
|
79
|
+
ActiveModelSerializers::LookupChain::BY_RESOURCE_NAMESPACE,
|
|
80
|
+
ActiveModelSerializers::LookupChain::BY_RESOURCE
|
|
81
|
+
]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Each of the array entries represent a proc. A serializer lookup proc will be yielded 3 arguments. `resource_class`, `serializer_class`, and `namespace`.
|
|
85
|
+
|
|
86
|
+
Note that:
|
|
87
|
+
- `resource_class` is the class of the resource being rendered
|
|
88
|
+
- by default `serializer_class` is `ActiveModel::Serializer`
|
|
89
|
+
- for association lookup it's the "parent" serializer
|
|
90
|
+
- `namespace` correspond to either the controller namespace or the [optionally] specified [namespace render option](./rendering.md#namespace)
|
|
91
|
+
|
|
92
|
+
An example config could be:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
ActiveModelSerializers.config.serializer_lookup_chain = [
|
|
96
|
+
lambda do |resource_class, serializer_class, namespace|
|
|
97
|
+
"API::#{namespace}::#{resource_class}"
|
|
98
|
+
end
|
|
99
|
+
]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
If you simply want to add to the existing lookup_chain. Use `unshift`.
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
ActiveModelSerializers.config.serializer_lookup_chain.unshift(
|
|
106
|
+
lambda do |resource_class, serializer_class, namespace|
|
|
107
|
+
# ...
|
|
108
|
+
end
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
See [lookup_chain.rb](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/lookup_chain.rb) for further explanations and examples.
|
|
113
|
+
|
|
114
|
+
## JSON API
|
|
115
|
+
|
|
116
|
+
##### jsonapi_resource_type
|
|
117
|
+
|
|
118
|
+
Sets whether the [type](http://jsonapi.org/format/#document-resource-identifier-objects)
|
|
119
|
+
of the resource should be `singularized` or `pluralized` when it is not
|
|
120
|
+
[explicitly specified by the serializer](https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#type)
|
|
121
|
+
|
|
122
|
+
Possible values:
|
|
123
|
+
|
|
124
|
+
- `:singular`
|
|
125
|
+
- `:plural` (default)
|
|
126
|
+
|
|
127
|
+
##### jsonapi_namespace_separator
|
|
128
|
+
|
|
129
|
+
Sets separator string for namespaced models to render `type` attribute.
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
| Separator | Example: Admin::User |
|
|
133
|
+
|----|----|
|
|
134
|
+
| `'-'` (default) | 'admin-users'
|
|
135
|
+
| `'--'` (recommended) | 'admin--users'
|
|
136
|
+
|
|
137
|
+
See [Recommendation for dasherizing (kebab-case-ing) namespaced object, such as `Admin::User`](https://github.com/json-api/json-api/issues/850)
|
|
138
|
+
for more discussion.
|
|
139
|
+
|
|
140
|
+
##### jsonapi_include_toplevel_object
|
|
141
|
+
|
|
142
|
+
Include a [top level jsonapi member](http://jsonapi.org/format/#document-jsonapi-object)
|
|
143
|
+
in the response document.
|
|
144
|
+
|
|
145
|
+
Possible values:
|
|
146
|
+
|
|
147
|
+
- `true`
|
|
148
|
+
- `false` (default)
|
|
149
|
+
|
|
150
|
+
##### jsonapi_version
|
|
151
|
+
|
|
152
|
+
The latest version of the spec to which the API conforms.
|
|
153
|
+
|
|
154
|
+
Default: `'1.0'`.
|
|
155
|
+
|
|
156
|
+
*Used when `jsonapi_include_toplevel_object` is `true`*
|
|
157
|
+
|
|
158
|
+
##### jsonapi_toplevel_meta
|
|
159
|
+
|
|
160
|
+
Optional top-level metadata. Not included if empty.
|
|
161
|
+
|
|
162
|
+
Default: `{}`.
|
|
163
|
+
|
|
164
|
+
*Used when `jsonapi_include_toplevel_object` is `true`*
|
|
165
|
+
|
|
166
|
+
##### jsonapi_use_foreign_key_on_belongs_to_relationship
|
|
167
|
+
|
|
168
|
+
When true, the relationship will determine its resource object identifier
|
|
169
|
+
without calling the association or its serializer. This can be useful when calling
|
|
170
|
+
the association object is triggering unnecessary queries.
|
|
171
|
+
|
|
172
|
+
For example, if a `comment` belongs to a `post`, and the comment
|
|
173
|
+
uses the foreign key `post_id`, we can determine the resource object
|
|
174
|
+
identifier `id` as `comment.post_id` and the `type` from the association options.
|
|
175
|
+
Or quite simply, it behaves as `belongs_to :post, type: :posts, foreign_key: :post_id`.
|
|
176
|
+
|
|
177
|
+
Note: This option has *no effect* on polymorphic associations as we cannot reliably
|
|
178
|
+
determine the associated object's type without instantiating it.
|
|
179
|
+
|
|
180
|
+
Default: `false`.
|
|
181
|
+
|
|
182
|
+
## Hooks
|
|
183
|
+
|
|
184
|
+
To run a hook when ActiveModelSerializers is loaded, use
|
|
185
|
+
`ActiveSupport.on_load(:action_controller) do end`
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Deserialization
|
|
4
|
+
|
|
5
|
+
This is currently an *experimental* feature. The interface may change.
|
|
6
|
+
|
|
7
|
+
## JSON API
|
|
8
|
+
|
|
9
|
+
The `ActiveModelSerializers::Deserialization` defines two methods (namely `jsonapi_parse` and `jsonapi_parse!`), which take a `Hash` or an instance of `ActionController::Parameters` representing a JSON API payload, and return a hash that can directly be used to create/update models. The bang version throws an `InvalidDocument` exception when parsing fails, whereas the "safe" version simply returns an empty hash.
|
|
10
|
+
|
|
11
|
+
- Parameters
|
|
12
|
+
- document: `Hash` or `ActionController::Parameters` instance
|
|
13
|
+
- options:
|
|
14
|
+
- only: `Array` of whitelisted fields
|
|
15
|
+
- except: `Array` of blacklisted fields
|
|
16
|
+
- keys: `Hash` of fields the name of which needs to be modified (e.g. `{ :author => :user, :date => :created_at }`)
|
|
17
|
+
|
|
18
|
+
Examples:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
class PostsController < ActionController::Base
|
|
22
|
+
def create
|
|
23
|
+
Post.create(create_params)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def create_params
|
|
27
|
+
ActiveModelSerializers::Deserialization.jsonapi_parse(params, only: [:title, :content, :author])
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Given a JSON API document,
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
document = {
|
|
38
|
+
'data' => {
|
|
39
|
+
'id' => 1,
|
|
40
|
+
'type' => 'post',
|
|
41
|
+
'attributes' => {
|
|
42
|
+
'title' => 'Title 1',
|
|
43
|
+
'date' => '2015-12-20'
|
|
44
|
+
},
|
|
45
|
+
'relationships' => {
|
|
46
|
+
'author' => {
|
|
47
|
+
'data' => {
|
|
48
|
+
'type' => 'user',
|
|
49
|
+
'id' => '2'
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
'second_author' => {
|
|
53
|
+
'data' => nil
|
|
54
|
+
},
|
|
55
|
+
'comments' => {
|
|
56
|
+
'data' => [{
|
|
57
|
+
'type' => 'comment',
|
|
58
|
+
'id' => '3'
|
|
59
|
+
},{
|
|
60
|
+
'type' => 'comment',
|
|
61
|
+
'id' => '4'
|
|
62
|
+
}]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The entire document can be parsed without specifying any options:
|
|
70
|
+
```ruby
|
|
71
|
+
ActiveModelSerializers::Deserialization.jsonapi_parse(document)
|
|
72
|
+
#=>
|
|
73
|
+
# {
|
|
74
|
+
# title: 'Title 1',
|
|
75
|
+
# date: '2015-12-20',
|
|
76
|
+
# author_id: 2,
|
|
77
|
+
# second_author_id: nil
|
|
78
|
+
# comment_ids: [3, 4]
|
|
79
|
+
# }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
and fields, relationships, and polymorphic relationships can be specified via the options:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
ActiveModelSerializers::Deserialization
|
|
86
|
+
.jsonapi_parse(document, only: [:title, :date, :author],
|
|
87
|
+
keys: { date: :published_at },
|
|
88
|
+
polymorphic: [:author])
|
|
89
|
+
#=>
|
|
90
|
+
# {
|
|
91
|
+
# title: 'Title 1',
|
|
92
|
+
# published_at: '2015-12-20',
|
|
93
|
+
# author_id: '2',
|
|
94
|
+
# author_type: 'user'
|
|
95
|
+
# }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Attributes/Json
|
|
99
|
+
|
|
100
|
+
There is currently no deserialization for those adapters.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Fields
|
|
4
|
+
|
|
5
|
+
If for any reason, you need to restrict the fields returned, you should use `fields` option.
|
|
6
|
+
|
|
7
|
+
For example, if you have a serializer like this
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
class UserSerializer < ActiveModel::Serializer
|
|
11
|
+
attributes :access_token, :first_name, :last_name
|
|
12
|
+
end
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
and in a specific controller, you want to return `access_token` only, `fields` will help you:
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
class AnonymousController < ApplicationController
|
|
19
|
+
def create
|
|
20
|
+
render json: User.create(activation_state: 'anonymous'), fields: [:access_token], status: 201
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Note that this is only valid for the `json` and `attributes` adapter. For the `json_api` adapter, you would use
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
render json: @user, fields: { users: [:access_token] }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Where `users` is the JSONAPI type.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Getting Started
|
|
4
|
+
|
|
5
|
+
## Creating a Serializer
|
|
6
|
+
|
|
7
|
+
The easiest way to create a new serializer is to generate a new resource, which
|
|
8
|
+
will generate a serializer at the same time:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
$ rails g resource post title:string body:string
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
This will generate a serializer in `app/serializers/post_serializer.rb` for
|
|
15
|
+
your new model. You can also generate a serializer for an existing model with
|
|
16
|
+
the serializer generator:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
$ rails g serializer post
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The generated serializer will contain basic `attributes` and
|
|
23
|
+
`has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
class PostSerializer < ActiveModel::Serializer
|
|
27
|
+
attributes :title, :body
|
|
28
|
+
|
|
29
|
+
has_many :comments
|
|
30
|
+
has_one :author
|
|
31
|
+
end
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
and
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
38
|
+
attributes :name, :body
|
|
39
|
+
|
|
40
|
+
belongs_to :post
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The attribute names are a **whitelist** of attributes to be serialized.
|
|
45
|
+
|
|
46
|
+
The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
|
|
47
|
+
resources. By default, when you serialize a `Post`, you will get its `Comments`
|
|
48
|
+
as well.
|
|
49
|
+
|
|
50
|
+
For more information, see [Serializers](/docs/general/serializers.md).
|
|
51
|
+
|
|
52
|
+
### Namespaced Models
|
|
53
|
+
|
|
54
|
+
When serializing a model inside a namespace, such as `Api::V1::Post`, ActiveModelSerializers will expect the corresponding serializer to be inside the same namespace (namely `Api::V1::PostSerializer`).
|
|
55
|
+
|
|
56
|
+
### Model Associations and Nested Serializers
|
|
57
|
+
|
|
58
|
+
When declaring a serializer for a model with associations, such as:
|
|
59
|
+
```ruby
|
|
60
|
+
class PostSerializer < ActiveModel::Serializer
|
|
61
|
+
has_many :comments
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
ActiveModelSerializers will look for `PostSerializer::CommentSerializer` in priority, and fall back to `::CommentSerializer` in case the former does not exist. This allows for more control over the way a model gets serialized as an association of an other model.
|
|
65
|
+
|
|
66
|
+
For example, in the following situation:
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
70
|
+
attributes :body, :date, :nb_likes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class PostSerializer < ActiveModel::Serializer
|
|
74
|
+
has_many :comments
|
|
75
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
76
|
+
attributes :body_short
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
ActiveModelSerializers will use `PostSerializer::CommentSerializer` (thus including only the `:body_short` attribute) when serializing a `Comment` as part of a `Post`, but use `::CommentSerializer` when serializing a `Comment` directly (thus including `:body, :date, :nb_likes`).
|
|
82
|
+
|
|
83
|
+
### Extending a Base `ApplicationSerializer`
|
|
84
|
+
|
|
85
|
+
By default, new serializers descend from `ActiveModel::Serializer`. However, if
|
|
86
|
+
you wish to share behavior across your serializers, you can create an
|
|
87
|
+
`ApplicationSerializer` at `app/serializers/application_serializer.rb`:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
class ApplicationSerializer < ActiveModel::Serializer
|
|
91
|
+
end
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then any newly-generated serializers will automatically descend from
|
|
95
|
+
`ApplicationSerializer`.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$ rails g serializer post
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Now generates:
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
class PostSerializer < ApplicationSerializer
|
|
105
|
+
attributes :id
|
|
106
|
+
end
|
|
107
|
+
````
|
|
108
|
+
|
|
109
|
+
## Rails Integration
|
|
110
|
+
|
|
111
|
+
ActiveModelSerializers will automatically integrate with your Rails app,
|
|
112
|
+
so you won't need to update your controller.
|
|
113
|
+
This is a example of how the controller will look:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
class PostsController < ApplicationController
|
|
117
|
+
|
|
118
|
+
def show
|
|
119
|
+
@post = Post.find(params[:id])
|
|
120
|
+
render json: @post
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
|
|
127
|
+
`Rails.application.routes.default_url_options`.
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
Rails.application.routes.default_url_options = {
|
|
131
|
+
host: 'example.com'
|
|
132
|
+
}
|
|
133
|
+
```
|