agi_active_model_serializers 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 +7 -0
- data/.github/ISSUE_TEMPLATE.md +29 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- data/.gitignore +35 -0
- data/.rubocop.yml +102 -0
- data/.simplecov +110 -0
- data/.travis.yml +51 -0
- data/CHANGELOG.md +612 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +105 -0
- data/Gemfile +56 -0
- data/MIT-LICENSE +22 -0
- data/README.md +307 -0
- data/Rakefile +103 -0
- data/active_model_serializers.gemspec +63 -0
- data/appveyor.yml +24 -0
- data/bin/bench +171 -0
- data/bin/bench_regression +316 -0
- data/bin/serve_benchmark +39 -0
- data/docs/README.md +41 -0
- data/docs/STYLE.md +58 -0
- data/docs/general/adapters.md +247 -0
- data/docs/general/caching.md +58 -0
- data/docs/general/configuration_options.md +169 -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 +14 -0
- data/docs/general/rendering.md +279 -0
- data/docs/general/serializers.md +461 -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 +137 -0
- data/docs/howto/add_root_key.md +55 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +65 -0
- data/docs/howto/passing_arbitrary_options.md +27 -0
- data/docs/howto/serialize_poro.md +32 -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 +144 -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 +66 -0
- data/lib/active_model/serializable_resource.rb +11 -0
- data/lib/active_model/serializer.rb +231 -0
- data/lib/active_model/serializer/adapter.rb +24 -0
- data/lib/active_model/serializer/adapter/attributes.rb +15 -0
- data/lib/active_model/serializer/adapter/base.rb +18 -0
- data/lib/active_model/serializer/adapter/json.rb +15 -0
- data/lib/active_model/serializer/adapter/json_api.rb +15 -0
- data/lib/active_model/serializer/adapter/null.rb +15 -0
- data/lib/active_model/serializer/array_serializer.rb +12 -0
- data/lib/active_model/serializer/association.rb +34 -0
- data/lib/active_model/serializer/attribute.rb +25 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +7 -0
- data/lib/active_model/serializer/collection_reflection.rb +7 -0
- data/lib/active_model/serializer/collection_serializer.rb +87 -0
- data/lib/active_model/serializer/concerns/associations.rb +102 -0
- data/lib/active_model/serializer/concerns/attributes.rb +82 -0
- data/lib/active_model/serializer/concerns/caching.rb +292 -0
- data/lib/active_model/serializer/concerns/configuration.rb +59 -0
- data/lib/active_model/serializer/concerns/links.rb +35 -0
- data/lib/active_model/serializer/concerns/meta.rb +29 -0
- data/lib/active_model/serializer/concerns/type.rb +25 -0
- data/lib/active_model/serializer/error_serializer.rb +14 -0
- data/lib/active_model/serializer/errors_serializer.rb +32 -0
- data/lib/active_model/serializer/field.rb +90 -0
- data/lib/active_model/serializer/fieldset.rb +31 -0
- data/lib/active_model/serializer/has_many_reflection.rb +7 -0
- data/lib/active_model/serializer/has_one_reflection.rb +7 -0
- data/lib/active_model/serializer/lint.rb +150 -0
- data/lib/active_model/serializer/null.rb +17 -0
- data/lib/active_model/serializer/reflection.rb +163 -0
- data/lib/active_model/serializer/singular_reflection.rb +7 -0
- data/lib/active_model/serializer/version.rb +5 -0
- data/lib/active_model_serializers.rb +53 -0
- data/lib/active_model_serializers/adapter.rb +98 -0
- data/lib/active_model_serializers/adapter/attributes.rb +13 -0
- data/lib/active_model_serializers/adapter/base.rb +83 -0
- data/lib/active_model_serializers/adapter/json.rb +21 -0
- data/lib/active_model_serializers/adapter/json_api.rb +517 -0
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +213 -0
- data/lib/active_model_serializers/adapter/json_api/error.rb +96 -0
- data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +49 -0
- data/lib/active_model_serializers/adapter/json_api/link.rb +83 -0
- data/lib/active_model_serializers/adapter/json_api/meta.rb +37 -0
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +69 -0
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +63 -0
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +51 -0
- data/lib/active_model_serializers/adapter/null.rb +9 -0
- data/lib/active_model_serializers/callbacks.rb +55 -0
- data/lib/active_model_serializers/deprecate.rb +54 -0
- data/lib/active_model_serializers/deserialization.rb +15 -0
- data/lib/active_model_serializers/json_pointer.rb +14 -0
- data/lib/active_model_serializers/logging.rb +122 -0
- data/lib/active_model_serializers/lookup_chain.rb +80 -0
- data/lib/active_model_serializers/model.rb +71 -0
- data/lib/active_model_serializers/railtie.rb +48 -0
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +78 -0
- data/lib/active_model_serializers/serializable_resource.rb +82 -0
- data/lib/active_model_serializers/serialization_context.rb +39 -0
- data/lib/active_model_serializers/test.rb +7 -0
- data/lib/active_model_serializers/test/schema.rb +138 -0
- data/lib/active_model_serializers/test/serializer.rb +125 -0
- data/lib/generators/rails/USAGE +6 -0
- data/lib/generators/rails/resource_override.rb +10 -0
- data/lib/generators/rails/serializer_generator.rb +36 -0
- data/lib/generators/rails/templates/serializer.rb.erb +15 -0
- data/lib/grape/active_model_serializers.rb +16 -0
- data/lib/grape/formatters/active_model_serializers.rb +32 -0
- data/lib/grape/helpers/active_model_serializers.rb +17 -0
- data/test/action_controller/adapter_selector_test.rb +53 -0
- data/test/action_controller/explicit_serializer_test.rb +135 -0
- data/test/action_controller/json/include_test.rb +246 -0
- data/test/action_controller/json_api/deserialization_test.rb +112 -0
- data/test/action_controller/json_api/errors_test.rb +40 -0
- data/test/action_controller/json_api/fields_test.rb +66 -0
- data/test/action_controller/json_api/linked_test.rb +202 -0
- data/test/action_controller/json_api/pagination_test.rb +116 -0
- data/test/action_controller/json_api/transform_test.rb +189 -0
- 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 +229 -0
- data/test/action_controller/serialization_test.rb +472 -0
- data/test/active_model_serializers/adapter_for_test.rb +208 -0
- data/test/active_model_serializers/json_pointer_test.rb +22 -0
- data/test/active_model_serializers/logging_test.rb +77 -0
- data/test/active_model_serializers/model_test.rb +69 -0
- data/test/active_model_serializers/railtie_test_isolated.rb +63 -0
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +71 -0
- data/test/active_model_serializers/test/schema_test.rb +131 -0
- data/test/active_model_serializers/test/serializer_test.rb +62 -0
- data/test/active_record_test.rb +9 -0
- data/test/adapter/attributes_test.rb +43 -0
- data/test/adapter/deprecation_test.rb +100 -0
- data/test/adapter/json/belongs_to_test.rb +45 -0
- data/test/adapter/json/collection_test.rb +104 -0
- data/test/adapter/json/has_many_test.rb +45 -0
- data/test/adapter/json/transform_test.rb +93 -0
- data/test/adapter/json_api/belongs_to_test.rb +155 -0
- data/test/adapter/json_api/collection_test.rb +96 -0
- data/test/adapter/json_api/errors_test.rb +76 -0
- data/test/adapter/json_api/fields_test.rb +96 -0
- data/test/adapter/json_api/has_many_embed_ids_test.rb +43 -0
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +96 -0
- data/test/adapter/json_api/has_many_test.rb +165 -0
- data/test/adapter/json_api/has_one_test.rb +80 -0
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +168 -0
- data/test/adapter/json_api/json_api_test.rb +33 -0
- data/test/adapter/json_api/linked_test.rb +413 -0
- data/test/adapter/json_api/links_test.rb +95 -0
- data/test/adapter/json_api/pagination_links_test.rb +193 -0
- data/test/adapter/json_api/parse_test.rb +137 -0
- data/test/adapter/json_api/relationship_test.rb +397 -0
- data/test/adapter/json_api/resource_identifier_test.rb +110 -0
- data/test/adapter/json_api/resource_meta_test.rb +100 -0
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +82 -0
- data/test/adapter/json_api/transform_test.rb +512 -0
- data/test/adapter/json_api/type_test.rb +61 -0
- data/test/adapter/json_test.rb +46 -0
- data/test/adapter/null_test.rb +22 -0
- data/test/adapter/polymorphic_test.rb +171 -0
- data/test/adapter_test.rb +67 -0
- data/test/array_serializer_test.rb +22 -0
- data/test/benchmark/app.rb +65 -0
- data/test/benchmark/benchmarking_support.rb +67 -0
- data/test/benchmark/bm_active_record.rb +81 -0
- data/test/benchmark/bm_adapter.rb +38 -0
- data/test/benchmark/bm_caching.rb +119 -0
- data/test/benchmark/bm_lookup_chain.rb +83 -0
- data/test/benchmark/bm_transform.rb +45 -0
- data/test/benchmark/config.ru +3 -0
- data/test/benchmark/controllers.rb +83 -0
- data/test/benchmark/fixtures.rb +219 -0
- data/test/cache_test.rb +595 -0
- data/test/collection_serializer_test.rb +123 -0
- data/test/fixtures/active_record.rb +113 -0
- data/test/fixtures/poro.rb +232 -0
- data/test/generators/scaffold_controller_generator_test.rb +24 -0
- data/test/generators/serializer_generator_test.rb +74 -0
- data/test/grape_test.rb +178 -0
- data/test/lint_test.rb +49 -0
- data/test/logger_test.rb +20 -0
- data/test/poro_test.rb +9 -0
- data/test/serializable_resource_test.rb +79 -0
- data/test/serializers/association_macros_test.rb +37 -0
- data/test/serializers/associations_test.rb +383 -0
- data/test/serializers/attribute_test.rb +153 -0
- data/test/serializers/attributes_test.rb +52 -0
- data/test/serializers/caching_configuration_test_isolated.rb +170 -0
- data/test/serializers/configuration_test.rb +32 -0
- data/test/serializers/fieldset_test.rb +14 -0
- data/test/serializers/meta_test.rb +202 -0
- data/test/serializers/options_test.rb +32 -0
- data/test/serializers/read_attribute_for_serialization_test.rb +79 -0
- data/test/serializers/root_test.rb +21 -0
- data/test/serializers/serialization_test.rb +55 -0
- data/test/serializers/serializer_for_test.rb +136 -0
- data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
- data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
- data/test/support/isolated_unit.rb +82 -0
- data/test/support/rails5_shims.rb +53 -0
- data/test/support/rails_app.rb +36 -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 +71 -0
- data/test/test_helper.rb +58 -0
- metadata +602 -0
|
@@ -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_id
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The attribute names are a **whitelist** of attributes to be serialized.
|
|
45
|
+
|
|
46
|
+
The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
|
|
47
|
+
resources. By default, when you serialize a `Post`, you will get its `Comments`
|
|
48
|
+
as well.
|
|
49
|
+
|
|
50
|
+
For more information, see [Serializers](/docs/general/serializers.md).
|
|
51
|
+
|
|
52
|
+
### Namespaced Models
|
|
53
|
+
|
|
54
|
+
When serializing a model inside a namespace, such as `Api::V1::Post`, ActiveModelSerializers will expect the corresponding serializer to be inside the same namespace (namely `Api::V1::PostSerializer`).
|
|
55
|
+
|
|
56
|
+
### Model Associations and Nested Serializers
|
|
57
|
+
|
|
58
|
+
When declaring a serializer for a model with associations, such as:
|
|
59
|
+
```ruby
|
|
60
|
+
class PostSerializer < ActiveModel::Serializer
|
|
61
|
+
has_many :comments
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
ActiveModelSerializers will look for `PostSerializer::CommentSerializer` in priority, and fall back to `::CommentSerializer` in case the former does not exist. This allows for more control over the way a model gets serialized as an association of an other model.
|
|
65
|
+
|
|
66
|
+
For example, in the following situation:
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
70
|
+
attributes :body, :date, :nb_likes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class PostSerializer < ActiveModel::Serializer
|
|
74
|
+
has_many :comments
|
|
75
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
76
|
+
attributes :body_short
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
ActiveModelSerializers will use `PostSerializer::CommentSerializer` (thus including only the `:body_short` attribute) when serializing a `Comment` as part of a `Post`, but use `::CommentSerializer` when serializing a `Comment` directly (thus including `:body, :date, :nb_likes`).
|
|
82
|
+
|
|
83
|
+
### Extending a Base `ApplicationSerializer`
|
|
84
|
+
|
|
85
|
+
By default, new serializers descend from `ActiveModel::Serializer`. However, if
|
|
86
|
+
you wish to share behavior across your serializers, you can create an
|
|
87
|
+
`ApplicationSerializer` at `app/serializers/application_serializer.rb`:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
class ApplicationSerializer < ActiveModel::Serializer
|
|
91
|
+
end
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then any newly-generated serializers will automatically descend from
|
|
95
|
+
`ApplicationSerializer`.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$ rails g serializer post
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Now generates:
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
class PostSerializer < ApplicationSerializer
|
|
105
|
+
attributes :id
|
|
106
|
+
end
|
|
107
|
+
````
|
|
108
|
+
|
|
109
|
+
## Rails Integration
|
|
110
|
+
|
|
111
|
+
ActiveModelSerializers will automatically integrate with your Rails app,
|
|
112
|
+
so you won't need to update your controller.
|
|
113
|
+
This is a example of how the controller will look:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
class PostsController < ApplicationController
|
|
117
|
+
|
|
118
|
+
def show
|
|
119
|
+
@post = Post.find(params[:id])
|
|
120
|
+
render json: @post
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
|
|
127
|
+
`Rails.application.routes.default_url_options`.
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
Rails.application.routes.default_url_options = {
|
|
131
|
+
host: 'example.com'
|
|
132
|
+
}
|
|
133
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Instrumentation
|
|
4
|
+
|
|
5
|
+
ActiveModelSerializers uses the
|
|
6
|
+
[ActiveSupport::Notification API](http://guides.rubyonrails.org/active_support_instrumentation.html#subscribing-to-an-event),
|
|
7
|
+
which allows for subscribing to events, such as for logging.
|
|
8
|
+
|
|
9
|
+
## Events
|
|
10
|
+
|
|
11
|
+
Name:
|
|
12
|
+
|
|
13
|
+
`render.active_model_serializers`
|
|
14
|
+
|
|
15
|
+
Payload (example):
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
{
|
|
19
|
+
serializer: PostSerializer,
|
|
20
|
+
adapter: ActiveModelSerializers::Adapter::Attributes
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Subscribing:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |name, started, finished, unique_id, data|
|
|
28
|
+
# whatever
|
|
29
|
+
end
|
|
30
|
+
ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |*args|
|
|
31
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
32
|
+
# event.payload
|
|
33
|
+
# whatever
|
|
34
|
+
end
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## [LogSubscriber](http://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html)
|
|
38
|
+
|
|
39
|
+
ActiveModelSerializers includes an `ActiveModelSerializers::LogSubscriber` that attaches to
|
|
40
|
+
`render.active_model_serializers`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Key Transforms
|
|
4
|
+
|
|
5
|
+
Key Transforms modify the casing of keys and keys referenced in values in
|
|
6
|
+
serialized responses.
|
|
7
|
+
|
|
8
|
+
Provided key transforms:
|
|
9
|
+
|
|
10
|
+
| Option | Result |
|
|
11
|
+
|----|----|
|
|
12
|
+
| `:camel` | ExampleKey |
|
|
13
|
+
| `:camel_lower` | exampleKey |
|
|
14
|
+
| `:dash` | example-key |
|
|
15
|
+
| `:unaltered` | the original, unaltered key |
|
|
16
|
+
| `:underscore` | example_key |
|
|
17
|
+
| `nil` | use the adapter default |
|
|
18
|
+
|
|
19
|
+
Key translation precedence is as follows:
|
|
20
|
+
|
|
21
|
+
##### Adapter option
|
|
22
|
+
|
|
23
|
+
`key_transform` is provided as an option via render.
|
|
24
|
+
|
|
25
|
+
```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
|
|
26
|
+
|
|
27
|
+
##### Configuration option
|
|
28
|
+
|
|
29
|
+
`key_transform` is set in `ActiveModelSerializers.config.key_transform`.
|
|
30
|
+
|
|
31
|
+
```ActiveModelSerializers.config.key_transform = :camel_lower```
|
|
32
|
+
|
|
33
|
+
##### Adapter default
|
|
34
|
+
|
|
35
|
+
Each adapter has a default transform configured:
|
|
36
|
+
|
|
37
|
+
| Adapter | Default Key Transform |
|
|
38
|
+
|----|----|
|
|
39
|
+
| `Json` | `:unaltered` |
|
|
40
|
+
| `JsonApi` | `:dash` |
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Logging
|
|
4
|
+
|
|
5
|
+
The default logger in a Rails application will be `Rails.logger`.
|
|
6
|
+
|
|
7
|
+
When there is no `Rails.logger`, the default logger is an instance of
|
|
8
|
+
`ActiveSupport::TaggedLogging` logging to STDOUT.
|
|
9
|
+
|
|
10
|
+
You may customize the logger in an initializer, for example:
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
ActiveModelSerializers.logger = Logger.new(STDOUT)
|
|
14
|
+
```
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
[Back to Guides](../README.md)
|
|
2
|
+
|
|
3
|
+
# Rendering
|
|
4
|
+
|
|
5
|
+
### Implicit Serializer
|
|
6
|
+
|
|
7
|
+
In your controllers, when you use `render :json`, Rails will now first search
|
|
8
|
+
for a serializer for the object and use it if available.
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
class PostsController < ApplicationController
|
|
12
|
+
def show
|
|
13
|
+
@post = Post.find(params[:id])
|
|
14
|
+
|
|
15
|
+
render json: @post
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
In this case, Rails will look for a serializer named `PostSerializer`, and if
|
|
21
|
+
it exists, use it to serialize the `Post`.
|
|
22
|
+
|
|
23
|
+
### Explicit Serializer
|
|
24
|
+
|
|
25
|
+
If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
|
|
26
|
+
|
|
27
|
+
#### 1. For a resource:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
render json: @post, serializer: PostPreviewSerializer
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
#### 2. For a resource collection:
|
|
34
|
+
|
|
35
|
+
Specify the serializer for each resource with `each_serializer`
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
render json: @posts, each_serializer: PostPreviewSerializer
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The default serializer for collections is `CollectionSerializer`.
|
|
42
|
+
|
|
43
|
+
Specify the collection serializer with the `serializer` option.
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Serializing non-ActiveRecord objects
|
|
50
|
+
|
|
51
|
+
See [README](../../README.md#what-does-a-serializable-resource-look-like)
|
|
52
|
+
|
|
53
|
+
## SerializableResource options
|
|
54
|
+
|
|
55
|
+
See [README](../../README.md#activemodelserializersserializableresource)
|
|
56
|
+
|
|
57
|
+
### adapter_opts
|
|
58
|
+
|
|
59
|
+
#### fields
|
|
60
|
+
|
|
61
|
+
If you are using `json` or `attributes` adapter
|
|
62
|
+
```ruby
|
|
63
|
+
render json: @user, fields: [:access_token]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
See [Fields](fields.md) for more information.
|
|
67
|
+
|
|
68
|
+
#### adapter
|
|
69
|
+
|
|
70
|
+
This option lets you explicitly set the adapter to be used by passing a registered adapter. Your options are `:attributes`, `:json`, and `:json_api`.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
ActiveModel::Serializer.config.adapter = :json_api
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### key_transform
|
|
77
|
+
|
|
78
|
+
```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
|
|
79
|
+
|
|
80
|
+
See [Key Transforms](key_transforms.md) for more information.
|
|
81
|
+
|
|
82
|
+
#### meta
|
|
83
|
+
|
|
84
|
+
A `meta` member can be used to include non-standard meta-information. `meta` can
|
|
85
|
+
be utilized in several levels in a response.
|
|
86
|
+
|
|
87
|
+
##### Top-level
|
|
88
|
+
|
|
89
|
+
To set top-level `meta` in a response, specify it in the `render` call.
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
render json: @post, meta: { total: 10 }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The key can be customized using `meta_key` option.
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`meta` will only be included in your response if you are using an Adapter that
|
|
102
|
+
supports `root`, e.g., `JsonApi` and `Json` adapters. The default adapter,
|
|
103
|
+
`Attributes` does not have `root`.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
##### Resource-level
|
|
107
|
+
|
|
108
|
+
To set resource-level `meta` in a response, define meta in a serializer with one
|
|
109
|
+
of the following methods:
|
|
110
|
+
|
|
111
|
+
As a single, static string.
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
meta stuff: 'value'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
As a block containing a Hash.
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
meta do
|
|
121
|
+
{
|
|
122
|
+
rating: 4,
|
|
123
|
+
comments_count: object.comments.count
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
#### links
|
|
130
|
+
|
|
131
|
+
If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
|
|
132
|
+
`Rails.application.routes.default_url_options`.
|
|
133
|
+
|
|
134
|
+
##### Top-level
|
|
135
|
+
|
|
136
|
+
JsonApi supports a [links object](http://jsonapi.org/format/#document-links) to be specified at top-level, that you can specify in the `render`:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
links_object = {
|
|
140
|
+
href: "http://example.com/api/posts",
|
|
141
|
+
meta: {
|
|
142
|
+
count: 10
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
render json: @posts, links: links_object
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
That's the result:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"data": [
|
|
153
|
+
{
|
|
154
|
+
"type": "posts",
|
|
155
|
+
"id": "1",
|
|
156
|
+
"attributes": {
|
|
157
|
+
"title": "JSON API is awesome!",
|
|
158
|
+
"body": "You should be using JSON API",
|
|
159
|
+
"created": "2015-05-22T14:56:29.000Z",
|
|
160
|
+
"updated": "2015-05-22T14:56:28.000Z"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"links": {
|
|
165
|
+
"href": "http://example.com/api/posts",
|
|
166
|
+
"meta": {
|
|
167
|
+
"count": 10
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
This feature is specific to JsonApi, so you have to use the use the [JsonApi Adapter](adapters.md#jsonapi)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
##### Resource-level
|
|
177
|
+
|
|
178
|
+
In your serializer, define each link in one of the following methods:
|
|
179
|
+
|
|
180
|
+
As a static string
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
link :link_name, 'https://example.com/resource'
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
As a block to be evaluated. When using Rails, URL helpers are available.
|
|
187
|
+
Ensure your application sets `Rails.application.routes.default_url_options`.
|
|
188
|
+
|
|
189
|
+
```ruby
|
|
190
|
+
link :link_name_ do
|
|
191
|
+
"https://example.com/resource/#{object.id}"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
link(:link_name) { "https://example.com/resource/#{object.id}" }
|
|
195
|
+
|
|
196
|
+
link(:link_name) { resource_url(object) }
|
|
197
|
+
|
|
198
|
+
link(:link_name) { url_for(controller: 'controller_name', action: 'index', only_path: false) }
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### serializer_opts
|
|
203
|
+
|
|
204
|
+
#### include
|
|
205
|
+
|
|
206
|
+
PR please :)
|
|
207
|
+
|
|
208
|
+
#### Overriding the root key
|
|
209
|
+
|
|
210
|
+
Overriding the resource root only applies when using the JSON adapter.
|
|
211
|
+
|
|
212
|
+
Normally, the resource root is derived from the class name of the resource being serialized.
|
|
213
|
+
e.g. `UserPostSerializer.new(UserPost.new)` will be serialized with the root `user_post` or `user_posts` according the adapter collection pluralization rules.
|
|
214
|
+
|
|
215
|
+
When using the JSON adapter in your initializer (ActiveModelSerializers.config.adapter = :json), or passing in the adapter in your render call, you can specify the root by passing it as an argument to `render`. For example:
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
render json: @user_post, root: "admin_post", adapter: :json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
This will be rendered as:
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"admin_post": {
|
|
225
|
+
"title": "how to do open source"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
Note: the `Attributes` adapter (default) does not include a resource root. You also will not be able to create a single top-level root if you are using the :json_api adapter.
|
|
230
|
+
|
|
231
|
+
#### namespace
|
|
232
|
+
|
|
233
|
+
The namespace for serializer lookup is based on the controller.
|
|
234
|
+
|
|
235
|
+
To configure the implicit namespace, in your controller, create a before filter
|
|
236
|
+
|
|
237
|
+
```ruby
|
|
238
|
+
before_action do
|
|
239
|
+
self.namespace_for_serializer = Api::V2
|
|
240
|
+
end
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
`namespace` can also be passed in as a render option:
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
```ruby
|
|
247
|
+
@post = Post.first
|
|
248
|
+
render json: @post, namespace: Api::V2
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
This tells the serializer lookup to check for the existence of `Api::V2::PostSerializer`, and if any relations are rendered with `@post`, they will also utilize the `Api::V2` namespace.
|
|
252
|
+
|
|
253
|
+
The `namespace` can be any object whose namespace can be represented by string interpolation (i.e. by calling to_s)
|
|
254
|
+
- Module `Api::V2`
|
|
255
|
+
- String `'Api::V2'`
|
|
256
|
+
- Symbol `:'Api::V2'`
|
|
257
|
+
|
|
258
|
+
Note that by using a string and symbol, Ruby will assume the namespace is defined at the top level.
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
#### serializer
|
|
262
|
+
|
|
263
|
+
PR please :)
|
|
264
|
+
|
|
265
|
+
#### scope
|
|
266
|
+
|
|
267
|
+
PR please :)
|
|
268
|
+
|
|
269
|
+
#### scope_name
|
|
270
|
+
|
|
271
|
+
PR please :)
|
|
272
|
+
|
|
273
|
+
## Using a serializer without `render`
|
|
274
|
+
|
|
275
|
+
See [Usage outside of a controller](../howto/outside_controller_use.md#serializing-before-controller-render).
|
|
276
|
+
|
|
277
|
+
## Pagination
|
|
278
|
+
|
|
279
|
+
See [How to add pagination links](https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md).
|