active_model_serializers 0.10.0 → 0.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -4
  3. data/.travis.yml +17 -5
  4. data/CHANGELOG.md +112 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +5 -2
  7. data/README.md +166 -26
  8. data/Rakefile +3 -3
  9. data/active_model_serializers.gemspec +21 -24
  10. data/appveyor.yml +9 -3
  11. data/docs/README.md +2 -1
  12. data/docs/general/adapters.md +4 -2
  13. data/docs/general/caching.md +7 -1
  14. data/docs/general/configuration_options.md +70 -1
  15. data/docs/general/deserialization.md +1 -1
  16. data/docs/general/fields.md +31 -0
  17. data/docs/general/logging.md +7 -0
  18. data/docs/general/rendering.md +44 -20
  19. data/docs/general/serializers.md +100 -11
  20. data/docs/howto/add_pagination_links.md +15 -16
  21. data/docs/howto/add_relationship_links.md +140 -0
  22. data/docs/howto/add_root_key.md +4 -0
  23. data/docs/howto/grape_integration.md +42 -0
  24. data/docs/howto/outside_controller_use.md +12 -4
  25. data/docs/howto/passing_arbitrary_options.md +2 -2
  26. data/docs/howto/serialize_poro.md +46 -5
  27. data/docs/howto/test.md +2 -0
  28. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  29. data/docs/integrations/ember-and-json-api.md +64 -32
  30. data/docs/jsonapi/schema.md +1 -1
  31. data/lib/action_controller/serialization.rb +13 -3
  32. data/lib/active_model/serializer/adapter/base.rb +2 -0
  33. data/lib/active_model/serializer/array_serializer.rb +8 -5
  34. data/lib/active_model/serializer/association.rb +19 -4
  35. data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
  36. data/lib/active_model/serializer/collection_serializer.rb +35 -12
  37. data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +13 -11
  38. data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +1 -1
  39. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +72 -113
  40. data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +25 -1
  41. data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
  42. data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
  43. data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
  44. data/lib/active_model/serializer/error_serializer.rb +11 -7
  45. data/lib/active_model/serializer/errors_serializer.rb +25 -20
  46. data/lib/active_model/serializer/has_many_reflection.rb +0 -3
  47. data/lib/active_model/serializer/has_one_reflection.rb +0 -3
  48. data/lib/active_model/serializer/lint.rb +134 -130
  49. data/lib/active_model/serializer/reflection.rb +37 -21
  50. data/lib/active_model/serializer/version.rb +1 -1
  51. data/lib/active_model/serializer.rb +76 -37
  52. data/lib/active_model_serializers/adapter/attributes.rb +3 -66
  53. data/lib/active_model_serializers/adapter/base.rb +39 -39
  54. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +1 -1
  55. data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
  56. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
  57. data/lib/active_model_serializers/adapter/json_api/relationship.rb +30 -19
  58. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
  59. data/lib/active_model_serializers/adapter/json_api.rb +44 -43
  60. data/lib/active_model_serializers/adapter.rb +6 -0
  61. data/lib/active_model_serializers/deprecate.rb +1 -2
  62. data/lib/active_model_serializers/deserialization.rb +2 -0
  63. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  64. data/lib/active_model_serializers/model.rb +108 -28
  65. data/lib/active_model_serializers/railtie.rb +3 -1
  66. data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
  67. data/lib/active_model_serializers/serializable_resource.rb +6 -5
  68. data/lib/active_model_serializers/serialization_context.rb +10 -3
  69. data/lib/active_model_serializers/test/schema.rb +2 -2
  70. data/lib/active_model_serializers.rb +15 -0
  71. data/lib/generators/rails/resource_override.rb +1 -1
  72. data/lib/generators/rails/serializer_generator.rb +4 -4
  73. data/lib/grape/active_model_serializers.rb +7 -5
  74. data/lib/grape/formatters/active_model_serializers.rb +19 -2
  75. data/lib/grape/helpers/active_model_serializers.rb +1 -0
  76. data/test/action_controller/adapter_selector_test.rb +14 -5
  77. data/test/action_controller/explicit_serializer_test.rb +5 -4
  78. data/test/action_controller/json/include_test.rb +106 -27
  79. data/test/action_controller/json_api/errors_test.rb +8 -9
  80. data/test/action_controller/json_api/fields_test.rb +66 -0
  81. data/test/action_controller/json_api/linked_test.rb +29 -24
  82. data/test/action_controller/json_api/pagination_test.rb +19 -19
  83. data/test/action_controller/json_api/transform_test.rb +11 -3
  84. data/test/action_controller/lookup_proc_test.rb +49 -0
  85. data/test/action_controller/namespace_lookup_test.rb +232 -0
  86. data/test/action_controller/serialization_scope_name_test.rb +12 -6
  87. data/test/action_controller/serialization_test.rb +12 -9
  88. data/test/active_model_serializers/json_pointer_test.rb +15 -13
  89. data/test/active_model_serializers/model_test.rb +137 -4
  90. data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
  91. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
  92. data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
  93. data/test/active_model_serializers/test/schema_test.rb +3 -2
  94. data/test/adapter/attributes_test.rb +40 -0
  95. data/test/adapter/json/collection_test.rb +14 -0
  96. data/test/adapter/json/has_many_test.rb +10 -2
  97. data/test/adapter/json/transform_test.rb +15 -15
  98. data/test/adapter/json_api/collection_test.rb +4 -3
  99. data/test/adapter/json_api/errors_test.rb +17 -19
  100. data/test/adapter/json_api/fields_test.rb +12 -3
  101. data/test/adapter/json_api/has_many_test.rb +49 -20
  102. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +183 -0
  103. data/test/adapter/json_api/json_api_test.rb +5 -7
  104. data/test/adapter/json_api/linked_test.rb +33 -12
  105. data/test/adapter/json_api/links_test.rb +4 -2
  106. data/test/adapter/json_api/pagination_links_test.rb +35 -8
  107. data/test/adapter/json_api/relationship_test.rb +309 -73
  108. data/test/adapter/json_api/resource_identifier_test.rb +27 -2
  109. data/test/adapter/json_api/resource_meta_test.rb +3 -3
  110. data/test/adapter/json_api/transform_test.rb +263 -253
  111. data/test/adapter/json_api/type_test.rb +1 -1
  112. data/test/adapter/json_test.rb +8 -7
  113. data/test/adapter/null_test.rb +1 -2
  114. data/test/adapter/polymorphic_test.rb +5 -5
  115. data/test/adapter_test.rb +1 -1
  116. data/test/benchmark/app.rb +1 -1
  117. data/test/benchmark/benchmarking_support.rb +1 -1
  118. data/test/benchmark/bm_active_record.rb +81 -0
  119. data/test/benchmark/bm_adapter.rb +38 -0
  120. data/test/benchmark/bm_caching.rb +16 -16
  121. data/test/benchmark/bm_lookup_chain.rb +83 -0
  122. data/test/benchmark/bm_transform.rb +21 -10
  123. data/test/benchmark/controllers.rb +16 -17
  124. data/test/benchmark/fixtures.rb +72 -72
  125. data/test/cache_test.rb +235 -69
  126. data/test/collection_serializer_test.rb +25 -12
  127. data/test/fixtures/active_record.rb +45 -10
  128. data/test/fixtures/poro.rb +124 -181
  129. data/test/generators/serializer_generator_test.rb +23 -5
  130. data/test/grape_test.rb +170 -56
  131. data/test/lint_test.rb +1 -1
  132. data/test/logger_test.rb +13 -11
  133. data/test/serializable_resource_test.rb +18 -22
  134. data/test/serializers/association_macros_test.rb +3 -2
  135. data/test/serializers/associations_test.rb +132 -36
  136. data/test/serializers/attribute_test.rb +5 -3
  137. data/test/serializers/attributes_test.rb +1 -1
  138. data/test/serializers/caching_configuration_test_isolated.rb +6 -6
  139. data/test/serializers/fieldset_test.rb +1 -1
  140. data/test/serializers/meta_test.rb +12 -6
  141. data/test/serializers/options_test.rb +17 -6
  142. data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
  143. data/test/serializers/root_test.rb +1 -1
  144. data/test/serializers/serialization_test.rb +2 -2
  145. data/test/serializers/serializer_for_test.rb +12 -10
  146. data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
  147. data/test/support/isolated_unit.rb +5 -2
  148. data/test/support/rails5_shims.rb +8 -2
  149. data/test/support/rails_app.rb +2 -9
  150. data/test/support/serialization_testing.rb +23 -5
  151. data/test/test_helper.rb +13 -0
  152. metadata +104 -38
  153. data/.rubocop_todo.yml +0 -167
  154. data/docs/ARCHITECTURE.md +0 -126
  155. data/lib/active_model/serializer/include_tree.rb +0 -111
  156. data/lib/active_model_serializers/key_transform.rb +0 -70
  157. data/test/active_model_serializers/key_transform_test.rb +0 -263
  158. data/test/adapter/json_api/relationships_test.rb +0 -199
  159. data/test/include_tree/from_include_args_test.rb +0 -26
  160. data/test/include_tree/from_string_test.rb +0 -94
  161. data/test/include_tree/include_args_to_hash_test.rb +0 -64
data/appveyor.yml CHANGED
@@ -1,4 +1,4 @@
1
- version: '{build}'
1
+ version: 1.0.{build}-{branch}
2
2
 
3
3
  skip_tags: true
4
4
 
@@ -7,17 +7,23 @@ environment:
7
7
  matrix:
8
8
  - ruby_version: "Ruby21"
9
9
  - ruby_version: "Ruby21-x64"
10
- - ruby_version: "jruby-9.0.0.0"
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
16
+ - gem update --system
17
+ - gem uninstall bundler -a -x
18
+ - gem install bundler -v 1.13.7
18
19
  - bundle env
19
20
  - bundle install --path=vendor/bundle --retry=3 --jobs=3
20
21
 
22
+ before_test:
23
+ - ruby -v
24
+ - gem -v
25
+ - bundle -v
26
+
21
27
  test_script:
22
28
  - bundle exec rake ci
23
29
 
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
 
@@ -67,9 +67,11 @@ Doesn't follow any specific convention.
67
67
 
68
68
  ### JSON
69
69
 
70
- The response document always with a root key.
70
+ The json response is always rendered with a root key.
71
71
 
72
- The root key **can't be overridden**, and will be derived from the resource being serialized.
72
+ The root key can be overridden by:
73
+ * passing the `root` option in the render call. See details in the [Rendering Guides](rendering.md#overriding-the-root-key).
74
+ * setting the `type` of the serializer. See details in the [Serializers Guide](serializers.md#type).
73
75
 
74
76
  Doesn't follow any specific convention.
75
77
 
@@ -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 bellow:
26
+ Take the example below:
21
27
 
22
28
  ```ruby
23
29
  class PostSerializer < ActiveModel::Serializer
@@ -46,15 +46,71 @@ Each adapter has a default key transform configured:
46
46
 
47
47
  | Adapter | Default Key Transform |
48
48
  |----|----|
49
+ | `Attributes` | `:unaltered` |
49
50
  | `Json` | `:unaltered` |
50
51
  | `JsonApi` | `:dash` |
51
52
 
52
53
  `config.key_transform` is a global override of the adapter default. Adapters
53
54
  still prefer the render option `:key_transform` over this setting.
54
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.*
55
58
 
56
- ## JSON API
59
+ ##### default_includes
60
+ What relationships to serialize by default. Default: `'*'`, which includes one level of related
61
+ objects. See [includes](adapters.md#included) for more info.
62
+
63
+
64
+ ##### serializer_lookup_chain
65
+
66
+ Configures how serializers are searched for. By default, the lookup chain is
67
+
68
+ ```ruby
69
+ ActiveModelSerializers::LookupChain::DEFAULT
70
+ ```
71
+
72
+ which is shorthand for
73
+
74
+ ```ruby
75
+ [
76
+ ActiveModelSerializers::LookupChain::BY_PARENT_SERIALIZER,
77
+ ActiveModelSerializers::LookupChain::BY_NAMESPACE,
78
+ ActiveModelSerializers::LookupChain::BY_RESOURCE_NAMESPACE,
79
+ ActiveModelSerializers::LookupChain::BY_RESOURCE
80
+ ]
81
+ ```
82
+
83
+ Each of the array entries represent a proc. A serializer lookup proc will be yielded 3 arguments. `resource_class`, `serializer_class`, and `namespace`.
84
+
85
+ Note that:
86
+ - `resource_class` is the class of the resource being rendered
87
+ - by default `serializer_class` is `ActiveModel::Serializer`
88
+ - for association lookup it's the "parent" serializer
89
+ - `namespace` correspond to either the controller namespace or the [optionally] specified [namespace render option](./rendering.md#namespace)
90
+
91
+ An example config could be:
92
+
93
+ ```ruby
94
+ ActiveModelSerializers.config.serializer_lookup_chain = [
95
+ lambda do |resource_class, serializer_class, namespace|
96
+ "API::#{namespace}::#{resource_class}"
97
+ end
98
+ ]
99
+ ```
57
100
 
101
+ If you simply want to add to the existing lookup_chain. Use `unshift`.
102
+
103
+ ```ruby
104
+ ActiveModelSerializers.config.serializer_lookup_chain.unshift(
105
+ lambda do |resource_class, serializer_class, namespace|
106
+ # ...
107
+ end
108
+ )
109
+ ```
110
+
111
+ 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.
112
+
113
+ ## JSON API
58
114
 
59
115
  ##### jsonapi_resource_type
60
116
 
@@ -67,6 +123,19 @@ Possible values:
67
123
  - `:singular`
68
124
  - `:plural` (default)
69
125
 
126
+ ##### jsonapi_namespace_separator
127
+
128
+ Sets separator string for namespaced models to render `type` attribute.
129
+
130
+
131
+ | Separator | Example: Admin::User |
132
+ |----|----|
133
+ | `'-'` (default) | 'admin-users'
134
+ | `'--'` (recommended) | 'admin--users'
135
+
136
+ See [Recommendation for dasherizing (kebab-case-ing) namespaced object, such as `Admin::User`](https://github.com/json-api/json-api/issues/850)
137
+ for more discussion.
138
+
70
139
  ##### jsonapi_include_toplevel_object
71
140
 
72
141
  Include a [top level jsonapi member](http://jsonapi.org/format/#document-jsonapi-object)
@@ -42,7 +42,7 @@ document = {
42
42
  'title' => 'Title 1',
43
43
  'date' => '2015-12-20'
44
44
  },
45
- 'associations' => {
45
+ 'relationships' => {
46
46
  'author' => {
47
47
  'data' => {
48
48
  'type' => 'user',
@@ -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.
@@ -12,3 +12,10 @@ You may customize the logger in an initializer, for example:
12
12
  ```ruby
13
13
  ActiveModelSerializers.logger = Logger.new(STDOUT)
14
14
  ```
15
+
16
+ You can also disable the logger, just put this in `config/initializers/active_model_serializers.rb`:
17
+
18
+ ```ruby
19
+ require 'active_model_serializers'
20
+ ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT)
21
+ ```
@@ -48,42 +48,36 @@ render json: @posts, serializer: CollectionSerializer, each_serializer: PostPrev
48
48
 
49
49
  ## Serializing non-ActiveRecord objects
50
50
 
51
- All serializable resources must pass the
52
- [ActiveModel::Serializer::Lint::Tests](../../lib/active_model/serializer/lint.rb#L17).
53
-
54
- See the ActiveModelSerializers::Model for a base class that implements the full
55
- API for a plain-old Ruby object (PORO).
51
+ See [README](../../README.md#what-does-a-serializable-resource-look-like)
56
52
 
57
53
  ## SerializableResource options
58
54
 
59
- The `options` hash passed to `render` or `ActiveModelSerializers::SerializableResource.new(resource, options)`
60
- are partitioned into `serializer_opts` and `adapter_opts`. `adapter_opts` are passed to new Adapters;
61
- `serializer_opts` are passed to new Serializers.
62
-
63
- The `adapter_opts` are specified in [ActiveModelSerializers::SerializableResource::ADAPTER_OPTIONS](../../lib/active_model_serializers/serializable_resource.rb#L5).
64
- The `serializer_opts` are the remaining options.
65
-
66
- (In Rails, the `options` are also passed to the `as_json(options)` or `to_json(options)`
67
- methods on the resource serialization by the Rails JSON renderer. They are, therefore, important
68
- to know about, but not part of ActiveModelSerializers.)
69
-
70
- See [ARCHITECTURE](../ARCHITECTURE.md) for more information.
55
+ See [README](../../README.md#activemodelserializersserializableresource)
71
56
 
72
57
  ### adapter_opts
73
58
 
74
59
  #### fields
75
60
 
76
- PR please :)
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.
77
67
 
78
68
  #### adapter
79
69
 
80
- PR please :)
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
+ ```
81
75
 
82
76
  #### key_transform
83
77
 
84
78
  ```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
85
79
 
86
- See [Key Transforms](key_transforms.md) for more informaiton.
80
+ See [Key Transforms](key_transforms.md) for more information.
87
81
 
88
82
  #### meta
89
83
 
@@ -234,6 +228,36 @@ This will be rendered as:
234
228
  ```
235
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.
236
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
+
237
261
  #### serializer
238
262
 
239
263
  PR please :)
@@ -31,10 +31,21 @@ Serialization of the resource `title`
31
31
  |---------------------------- |-------------|
32
32
  | `attribute :title` | `{ title: 'Some Title' } `
33
33
  | `attribute :title, key: :name` | `{ name: 'Some Title' } `
34
- | `attribute :title { 'A Different Title'}` | `{ title: 'A Different Title' } `
34
+ | `attribute(:title) { 'A Different Title'}` | `{ title: 'A Different Title' } `
35
35
  | `attribute :title`<br>`def title 'A Different Title' end` | `{ title: 'A Different Title' }`
36
36
 
37
- [PR please for conditional attributes:)](https://github.com/rails-api/active_model_serializers/pull/1403)
37
+ An `if` or `unless` option can make an attribute conditional. It takes a symbol of a method name on the serializer, or a lambda literal.
38
+
39
+ e.g.
40
+
41
+ ```ruby
42
+ attribute :private_data, if: :is_current_user?
43
+ attribute :another_private_data, if: -> { scope.admin? }
44
+
45
+ def is_current_user?
46
+ object.id == current_user.id
47
+ end
48
+ ```
38
49
 
39
50
  ### Associations
40
51
 
@@ -129,7 +140,7 @@ class PictureSerializer < ActiveModel::Serializer
129
140
  end
130
141
  ```
131
142
 
132
- For more context, see the [tests](../../test/adapter/polymorphic_test.rb) for each adapter.
143
+ You can specify the serializers by [overriding serializer_for](serializers.md#overriding-association-serializer-lookup). For more context about polymorphic relationships, see the [tests](../../test/adapter/polymorphic_test.rb) for each adapter.
133
144
 
134
145
  ### Caching
135
146
 
@@ -162,18 +173,25 @@ end
162
173
 
163
174
  #### ::type
164
175
 
165
- The `::type` method defines the JSONAPI [type](http://jsonapi.org/format/#document-resource-object-identification) that will be rendered for this serializer.
176
+ When using the `:json_api` adapter, the `::type` method defines the JSONAPI [type](http://jsonapi.org/format/#document-resource-object-identification) that will be rendered for this serializer.
177
+
178
+ When using the `:json` adapter, the `::type` method defines the name of the root element.
179
+
166
180
  It either takes a `String` or `Symbol` as parameter.
167
181
 
168
- Note: This method is useful only when using the `:json_api` adapter.
182
+ Note: This method is useful only when using the `:json_api` or `:json` adapter.
169
183
 
170
184
  Examples:
171
185
  ```ruby
172
186
  class UserProfileSerializer < ActiveModel::Serializer
173
187
  type 'profile'
188
+
189
+ attribute :name
174
190
  end
175
191
  class AuthorProfileSerializer < ActiveModel::Serializer
176
192
  type :profile
193
+
194
+ attribute :name
177
195
  end
178
196
  ```
179
197
 
@@ -183,7 +201,20 @@ With the `:json_api` adapter, the previous serializers would be rendered as:
183
201
  {
184
202
  "data": {
185
203
  "id": "1",
186
- "type": "profile"
204
+ "type": "profile",
205
+ "attributes": {
206
+ "name": "Julia"
207
+ }
208
+ }
209
+ }
210
+ ```
211
+
212
+ With the `:json` adapter, the previous serializer would be rendered as:
213
+
214
+ ``` json
215
+ {
216
+ "profile": {
217
+ "name": "Julia"
187
218
  }
188
219
  }
189
220
  ```
@@ -194,10 +225,10 @@ With the `:json_api` adapter, the previous serializers would be rendered as:
194
225
  link :self do
195
226
  href "https://example.com/link_author/#{object.id}"
196
227
  end
197
- link :author { link_author_url(object) }
198
- link :link_authors { link_authors_url }
228
+ link(:author) { link_author_url(object) }
229
+ link(:link_authors) { link_authors_url }
199
230
  link :other, 'https://example.com/resource'
200
- link :posts { link_author_posts_url(object) }
231
+ link(:posts) { link_author_posts_url(object) }
201
232
  ```
202
233
 
203
234
  #### #object
@@ -206,7 +237,17 @@ The object being serialized.
206
237
 
207
238
  #### #root
208
239
 
209
- PR please :)
240
+ Resource root which is included in `JSON` adapter. As you can see at [Adapters Document](adapters.md), `Attribute` adapter (default) and `JSON API` adapter does not include root at top level.
241
+ By default, the resource root comes from the `model_name` of the serialized object's class.
242
+
243
+ There are several ways to specify root:
244
+ * [Overriding the root key](rendering.md#overriding-the-root-key)
245
+ * [Setting `type`](serializers.md#type)
246
+ * Specifying the `root` option, e.g. `root: 'specific_name'`, during the serializer's initialization:
247
+
248
+ ```ruby
249
+ ActiveModelSerializers::SerializableResource.new(foo, root: 'bar')
250
+ ```
210
251
 
211
252
  #### #scope
212
253
 
@@ -255,7 +296,7 @@ In the controller, the scope/scope_name options are equal to
255
296
  the [`serialization_scope`method](https://github.com/rails-api/active_model_serializers/blob/d02cd30fe55a3ea85e1d351b6e039620903c1871/lib/action_controller/serialization.rb#L13-L20),
256
297
  which is `:current_user`, by default.
257
298
 
258
- Specfically, the `scope_name` is defaulted to `:current_user`, and may be set as
299
+ Specifically, the `scope_name` is defaulted to `:current_user`, and may be set as
259
300
  `serialization_scope :view_context`. The `scope` is set to `send(scope_name)` when `scope_name` is
260
301
  present and the controller responds to `scope_name`.
261
302
 
@@ -303,6 +344,38 @@ So that when we render the `#edit` action, we'll get
303
344
 
304
345
  Where `can_edit` is `view_context.current_user.admin?` (true).
305
346
 
347
+ You can also tell what to set as `serialization_scope` for specific actions.
348
+
349
+ For example, use `admin_user` only for `Admin::PostSerializer` and `current_user` for rest.
350
+
351
+ ```ruby
352
+ class PostsController < ActionController::Base
353
+
354
+ before_action only: :edit do
355
+ self.class.serialization_scope :admin_user
356
+ end
357
+
358
+ def show
359
+ render json: @post, serializer: PostSerializer
360
+ end
361
+
362
+ def edit
363
+ @post.save
364
+ render json: @post, serializer: Admin::PostSerializer
365
+ end
366
+
367
+ private
368
+
369
+ def admin_user
370
+ User.new(id: 2, name: 'Bob', admin: true)
371
+ end
372
+
373
+ def current_user
374
+ User.new(id: 2, name: 'Bob', admin: false)
375
+ end
376
+ end
377
+ ```
378
+
306
379
  #### #read_attribute_for_serialization(key)
307
380
 
308
381
  The serialized value for a given key. e.g. `read_attribute_for_serialization(:title) #=> 'Hello World'`
@@ -370,3 +443,19 @@ class PostSerializer < ActiveModel::Serializer
370
443
  end
371
444
  end
372
445
  ```
446
+
447
+ ## Overriding association serializer lookup
448
+
449
+ If you want to define a specific serializer lookup for your associations, you can override
450
+ the `ActiveModel::Serializer.serializer_for` method to return a serializer class based on defined conditions.
451
+
452
+ ```ruby
453
+ class MySerializer < ActiveModel::Serializer
454
+ def self.serializer_for(model, options)
455
+ return SparseAdminSerializer if model.class == 'Admin'
456
+ super
457
+ end
458
+
459
+ # the rest of the serializer
460
+ end
461
+ ```
@@ -10,9 +10,9 @@ the resource is paginated and if you are using the ```JsonApi``` adapter.
10
10
  If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari)
11
11
  or [WillPaginate](https://github.com/mislav/will_paginate).
12
12
 
13
- Although the others adapters does not have this feature, it is possible to
13
+ Although the other adapters do not have this feature, it is possible to
14
14
  implement pagination links to `JSON` adapter. For more information about it,
15
- please see in our docs
15
+ please check our docs.
16
16
 
17
17
  ###### Kaminari examples
18
18
 
@@ -77,13 +77,13 @@ If you are using `JSON` adapter, pagination links will not be included automatic
77
77
  Add this method to your base API controller.
78
78
 
79
79
  ```ruby
80
- def pagination_dict(object)
80
+ def pagination_dict(collection)
81
81
  {
82
- current_page: object.current_page,
83
- next_page: object.next_page,
84
- prev_page: object.prev_page,
85
- total_pages: object.total_pages,
86
- total_count: object.total_count
82
+ current_page: collection.current_page,
83
+ next_page: collection.next_page,
84
+ prev_page: collection.prev_page, # use collection.previous_page when using will_paginate
85
+ total_pages: collection.total_pages,
86
+ total_count: collection.total_count
87
87
  }
88
88
  end
89
89
  ```
@@ -117,23 +117,22 @@ ex.
117
117
  You can also achieve the same result if you have a helper method that adds the pagination info in the meta tag. For instance, in your action specify a custom serializer.
118
118
 
119
119
  ```ruby
120
- render json: @posts, each_serializer: PostPreviewSerializer, meta: meta_attributes(@post)
120
+ render json: @posts, each_serializer: PostPreviewSerializer, meta: meta_attributes(@posts)
121
121
  ```
122
122
 
123
123
  ```ruby
124
124
  #expects pagination!
125
- def meta_attributes(resource, extra_meta = {})
125
+ def meta_attributes(collection, extra_meta = {})
126
126
  {
127
- current_page: resource.current_page,
128
- next_page: resource.next_page,
129
- prev_page: resource.prev_page,
130
- total_pages: resource.total_pages,
131
- total_count: resource.total_count
127
+ current_page: collection.current_page,
128
+ next_page: collection.next_page,
129
+ prev_page: collection.prev_page, # use collection.previous_page when using will_paginate
130
+ total_pages: collection.total_pages,
131
+ total_count: collection.total_count
132
132
  }.merge(extra_meta)
133
133
  end
134
134
  ```
135
135
 
136
-
137
136
  ### Attributes adapter
138
137
 
139
138
  This adapter does not allow us to use `meta` key, due to that it is not possible to add pagination links.