active_model_serializers 0.10.0 → 0.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +6 -5
  3. data/.travis.yml +30 -21
  4. data/CHANGELOG.md +172 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +23 -4
  7. data/README.md +166 -28
  8. data/Rakefile +3 -32
  9. data/active_model_serializers.gemspec +22 -25
  10. data/appveyor.yml +10 -6
  11. data/bin/rubocop +38 -0
  12. data/docs/README.md +2 -1
  13. data/docs/general/adapters.md +35 -11
  14. data/docs/general/caching.md +7 -1
  15. data/docs/general/configuration_options.md +86 -1
  16. data/docs/general/deserialization.md +1 -1
  17. data/docs/general/fields.md +31 -0
  18. data/docs/general/getting_started.md +1 -1
  19. data/docs/general/logging.md +7 -0
  20. data/docs/general/rendering.md +63 -25
  21. data/docs/general/serializers.md +125 -14
  22. data/docs/howto/add_pagination_links.md +16 -17
  23. data/docs/howto/add_relationship_links.md +140 -0
  24. data/docs/howto/add_root_key.md +11 -0
  25. data/docs/howto/grape_integration.md +42 -0
  26. data/docs/howto/outside_controller_use.md +12 -4
  27. data/docs/howto/passing_arbitrary_options.md +2 -2
  28. data/docs/howto/serialize_poro.md +46 -5
  29. data/docs/howto/test.md +2 -0
  30. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  31. data/docs/integrations/ember-and-json-api.md +67 -32
  32. data/docs/jsonapi/schema.md +1 -1
  33. data/lib/action_controller/serialization.rb +13 -3
  34. data/lib/active_model/serializer/adapter/base.rb +2 -0
  35. data/lib/active_model/serializer/array_serializer.rb +8 -5
  36. data/lib/active_model/serializer/association.rb +62 -10
  37. data/lib/active_model/serializer/belongs_to_reflection.rb +4 -3
  38. data/lib/active_model/serializer/collection_serializer.rb +39 -13
  39. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +82 -115
  40. data/lib/active_model/serializer/error_serializer.rb +11 -7
  41. data/lib/active_model/serializer/errors_serializer.rb +25 -20
  42. data/lib/active_model/serializer/has_many_reflection.rb +3 -3
  43. data/lib/active_model/serializer/has_one_reflection.rb +1 -4
  44. data/lib/active_model/serializer/lazy_association.rb +95 -0
  45. data/lib/active_model/serializer/lint.rb +134 -130
  46. data/lib/active_model/serializer/reflection.rb +127 -67
  47. data/lib/active_model/serializer/version.rb +1 -1
  48. data/lib/active_model/serializer.rb +297 -79
  49. data/lib/active_model_serializers/adapter/attributes.rb +3 -66
  50. data/lib/active_model_serializers/adapter/base.rb +39 -39
  51. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +2 -2
  52. data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
  53. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +47 -21
  54. data/lib/active_model_serializers/adapter/json_api/relationship.rb +75 -23
  55. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +39 -10
  56. data/lib/active_model_serializers/adapter/json_api.rb +71 -57
  57. data/lib/active_model_serializers/adapter.rb +6 -0
  58. data/lib/active_model_serializers/deprecate.rb +1 -2
  59. data/lib/active_model_serializers/deserialization.rb +2 -0
  60. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  61. data/lib/active_model_serializers/model.rb +109 -28
  62. data/lib/active_model_serializers/railtie.rb +3 -1
  63. data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
  64. data/lib/active_model_serializers/serializable_resource.rb +6 -5
  65. data/lib/active_model_serializers/serialization_context.rb +10 -3
  66. data/lib/active_model_serializers/test/schema.rb +2 -2
  67. data/lib/active_model_serializers.rb +16 -1
  68. data/lib/generators/rails/resource_override.rb +1 -1
  69. data/lib/generators/rails/serializer_generator.rb +4 -4
  70. data/lib/grape/active_model_serializers.rb +7 -5
  71. data/lib/grape/formatters/active_model_serializers.rb +19 -2
  72. data/lib/grape/helpers/active_model_serializers.rb +1 -0
  73. data/lib/tasks/rubocop.rake +53 -0
  74. data/test/action_controller/adapter_selector_test.rb +14 -5
  75. data/test/action_controller/explicit_serializer_test.rb +5 -4
  76. data/test/action_controller/json/include_test.rb +106 -27
  77. data/test/action_controller/json_api/deserialization_test.rb +1 -1
  78. data/test/action_controller/json_api/errors_test.rb +8 -9
  79. data/test/action_controller/json_api/fields_test.rb +66 -0
  80. data/test/action_controller/json_api/linked_test.rb +29 -24
  81. data/test/action_controller/json_api/pagination_test.rb +31 -23
  82. data/test/action_controller/json_api/transform_test.rb +11 -3
  83. data/test/action_controller/lookup_proc_test.rb +49 -0
  84. data/test/action_controller/namespace_lookup_test.rb +232 -0
  85. data/test/action_controller/serialization_scope_name_test.rb +12 -6
  86. data/test/action_controller/serialization_test.rb +12 -9
  87. data/test/active_model_serializers/json_pointer_test.rb +15 -13
  88. data/test/active_model_serializers/model_test.rb +137 -4
  89. data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
  90. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
  91. data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
  92. data/test/active_model_serializers/test/schema_test.rb +3 -2
  93. data/test/adapter/attributes_test.rb +40 -0
  94. data/test/adapter/json/collection_test.rb +14 -0
  95. data/test/adapter/json/has_many_test.rb +10 -2
  96. data/test/adapter/json/transform_test.rb +15 -15
  97. data/test/adapter/json_api/collection_test.rb +4 -3
  98. data/test/adapter/json_api/errors_test.rb +17 -19
  99. data/test/adapter/json_api/fields_test.rb +12 -3
  100. data/test/adapter/json_api/has_many_test.rb +49 -20
  101. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +213 -0
  102. data/test/adapter/json_api/json_api_test.rb +5 -7
  103. data/test/adapter/json_api/linked_test.rb +33 -12
  104. data/test/adapter/json_api/links_test.rb +4 -2
  105. data/test/adapter/json_api/pagination_links_test.rb +53 -13
  106. data/test/adapter/json_api/parse_test.rb +1 -1
  107. data/test/adapter/json_api/relationship_test.rb +309 -73
  108. data/test/adapter/json_api/resource_meta_test.rb +3 -3
  109. data/test/adapter/json_api/transform_test.rb +263 -253
  110. data/test/adapter/json_api/type_test.rb +168 -36
  111. data/test/adapter/json_test.rb +8 -7
  112. data/test/adapter/null_test.rb +1 -2
  113. data/test/adapter/polymorphic_test.rb +52 -5
  114. data/test/adapter_test.rb +1 -1
  115. data/test/benchmark/app.rb +1 -1
  116. data/test/benchmark/benchmarking_support.rb +1 -1
  117. data/test/benchmark/bm_active_record.rb +81 -0
  118. data/test/benchmark/bm_adapter.rb +38 -0
  119. data/test/benchmark/bm_caching.rb +16 -16
  120. data/test/benchmark/bm_lookup_chain.rb +83 -0
  121. data/test/benchmark/bm_transform.rb +21 -10
  122. data/test/benchmark/controllers.rb +16 -17
  123. data/test/benchmark/fixtures.rb +72 -72
  124. data/test/cache_test.rb +235 -69
  125. data/test/collection_serializer_test.rb +31 -14
  126. data/test/fixtures/active_record.rb +45 -10
  127. data/test/fixtures/poro.rb +124 -181
  128. data/test/generators/serializer_generator_test.rb +23 -5
  129. data/test/grape_test.rb +170 -56
  130. data/test/lint_test.rb +1 -1
  131. data/test/logger_test.rb +13 -11
  132. data/test/serializable_resource_test.rb +18 -22
  133. data/test/serializers/association_macros_test.rb +3 -2
  134. data/test/serializers/associations_test.rb +222 -49
  135. data/test/serializers/attribute_test.rb +5 -3
  136. data/test/serializers/attributes_test.rb +1 -1
  137. data/test/serializers/caching_configuration_test_isolated.rb +6 -6
  138. data/test/serializers/fieldset_test.rb +1 -1
  139. data/test/serializers/meta_test.rb +12 -6
  140. data/test/serializers/options_test.rb +17 -6
  141. data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
  142. data/test/serializers/reflection_test.rb +427 -0
  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 +9 -4
  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 +31 -5
  151. data/test/test_helper.rb +13 -0
  152. metadata +130 -71
  153. data/.rubocop_todo.yml +0 -167
  154. data/docs/ARCHITECTURE.md +0 -126
  155. data/lib/active_model/serializer/associations.rb +0 -100
  156. data/lib/active_model/serializer/attributes.rb +0 -82
  157. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  158. data/lib/active_model/serializer/configuration.rb +0 -35
  159. data/lib/active_model/serializer/include_tree.rb +0 -111
  160. data/lib/active_model/serializer/links.rb +0 -35
  161. data/lib/active_model/serializer/meta.rb +0 -29
  162. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  163. data/lib/active_model/serializer/type.rb +0 -25
  164. data/lib/active_model_serializers/key_transform.rb +0 -70
  165. data/test/active_model_serializers/key_transform_test.rb +0 -263
  166. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  167. data/test/adapter/json_api/relationships_test.rb +0 -199
  168. data/test/adapter/json_api/resource_identifier_test.rb +0 -85
  169. data/test/include_tree/from_include_args_test.rb +0 -26
  170. data/test/include_tree/from_string_test.rb +0 -94
  171. data/test/include_tree/include_args_to_hash_test.rb +0 -64
data/.rubocop_todo.yml DELETED
@@ -1,167 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2016-03-08 22:29:52 +0100 using RuboCop version 0.37.2.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 2
10
- Lint/HandleExceptions:
11
- Exclude:
12
- - 'Rakefile'
13
-
14
- # Offense count: 2
15
- # Cop supports --auto-correct.
16
- # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
17
- Lint/UnusedMethodArgument:
18
- Exclude:
19
- - 'test/lint_test.rb'
20
-
21
- # Offense count: 4
22
- # Configuration parameters: EnforcedStyle, SupportedStyles.
23
- # SupportedStyles: strict, flexible
24
- Rails/TimeZone:
25
- Exclude:
26
- - 'test/action_controller/serialization_test.rb'
27
- - 'test/serializers/cache_test.rb'
28
-
29
- # Offense count: 16
30
- # Cop supports --auto-correct.
31
- # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
32
- # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
33
- Style/AlignHash:
34
- Exclude:
35
- - 'test/action_controller/json_api/pagination_test.rb'
36
-
37
- # Offense count: 27
38
- # Cop supports --auto-correct.
39
- # Configuration parameters: EnforcedStyle, SupportedStyles.
40
- # SupportedStyles: braces, no_braces, context_dependent
41
- Style/BracesAroundHashParameters:
42
- Exclude:
43
- - 'test/action_controller/adapter_selector_test.rb'
44
- - 'test/action_controller/json_api/pagination_test.rb'
45
- - 'test/adapter/json_api/linked_test.rb'
46
- - 'test/adapter/json_api/pagination_links_test.rb'
47
- - 'test/adapter/null_test.rb'
48
- - 'test/adapter_test.rb'
49
- - 'test/collection_serializer_test.rb'
50
- - 'test/serializable_resource_test.rb'
51
- - 'test/serializers/associations_test.rb'
52
- - 'test/serializers/attributes_test.rb'
53
- - 'test/serializers/root_test.rb'
54
-
55
- # Offense count: 271
56
- # Configuration parameters: EnforcedStyle, SupportedStyles.
57
- # SupportedStyles: nested, compact
58
- Style/ClassAndModuleChildren:
59
- Enabled: false
60
-
61
- # Offense count: 6
62
- # Cop supports --auto-correct.
63
- Style/CommentIndentation:
64
- Exclude:
65
- - 'active_model_serializers.gemspec'
66
-
67
- # Offense count: 1
68
- Style/DoubleNegation:
69
- Exclude:
70
- - 'lib/active_model/serializable_resource.rb'
71
-
72
- # Offense count: 1
73
- # Configuration parameters: MinBodyLength.
74
- Style/GuardClause:
75
- Exclude:
76
- - 'lib/active_model/serializer.rb'
77
-
78
- # Offense count: 58
79
- # Cop supports --auto-correct.
80
- # Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues.
81
- # SupportedStyles: ruby19, ruby19_no_mixed_keys, hash_rockets
82
- Style/HashSyntax:
83
- Enabled: false
84
-
85
- # Offense count: 4
86
- # Cop supports --auto-correct.
87
- # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
88
- # SupportedStyles: special_inside_parentheses, consistent, align_brackets
89
- Style/IndentArray:
90
- Enabled: false
91
-
92
- # Offense count: 10
93
- # Cop supports --auto-correct.
94
- # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
95
- # SupportedStyles: special_inside_parentheses, consistent, align_braces
96
- Style/IndentHash:
97
- Enabled: false
98
-
99
- # Offense count: 1
100
- # Cop supports --auto-correct.
101
- Style/Lambda:
102
- Exclude:
103
- - 'lib/active_model/serializer.rb'
104
-
105
- # Offense count: 1
106
- # Cop supports --auto-correct.
107
- # Configuration parameters: EnforcedStyle, SupportedStyles.
108
- # SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline
109
- Style/MethodDefParentheses:
110
- Enabled: false
111
-
112
- # Offense count: 1
113
- # Cop supports --auto-correct.
114
- # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
115
- # SupportedStyles: aligned, indented
116
- Style/MultilineOperationIndentation:
117
- Enabled: false
118
-
119
- # Offense count: 1
120
- # Cop supports --auto-correct.
121
- Style/NegatedIf:
122
- Exclude:
123
- - 'lib/action_controller/serialization.rb'
124
-
125
- # Offense count: 1
126
- # Cop supports --auto-correct.
127
- Style/PerlBackrefs:
128
- Exclude:
129
- - 'test/fixtures/poro.rb'
130
-
131
- # Offense count: 3
132
- # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
133
- # NamePrefix: is_, has_, have_
134
- # NamePrefixBlacklist: is_, has_, have_
135
- # NameWhitelist: is_a?
136
- Style/PredicateName:
137
- Exclude:
138
- - 'lib/active_model/serializer/associations.rb'
139
- - 'test/action_controller/json_api/linked_test.rb'
140
-
141
- # Offense count: 1
142
- # Cop supports --auto-correct.
143
- Style/RedundantSelf:
144
- Exclude:
145
- - 'test/fixtures/poro.rb'
146
-
147
- # Offense count: 1
148
- # Cop supports --auto-correct.
149
- # Configuration parameters: AllowIfMethodIsEmpty.
150
- Style/SingleLineMethods:
151
- Exclude:
152
- - 'test/serializers/serializer_for_test.rb'
153
-
154
- # Offense count: 4
155
- # Cop supports --auto-correct.
156
- # Configuration parameters: EnforcedStyle, SupportedStyles.
157
- # SupportedStyles: single_quotes, double_quotes
158
- Style/StringLiteralsInInterpolation:
159
- Enabled: false
160
-
161
- # Offense count: 1
162
- # Cop supports --auto-correct.
163
- # Configuration parameters: EnforcedStyle, SupportedStyles.
164
- # SupportedStyles: final_newline, final_blank_line
165
- Style/TrailingBlankLines:
166
- Exclude:
167
- - 'test/adapter/null_test.rb'
data/docs/ARCHITECTURE.md DELETED
@@ -1,126 +0,0 @@
1
- [Back to Guides](README.md)
2
-
3
- This document focuses on architecture the 0.10.x version of ActiveModelSerializers. If you are interested in the architecture of the 0.8 or 0.9 versions,
4
- please refer to the [0.8 README](https://github.com/rails-api/active_model_serializers/blob/0-8-stable/README.md) or
5
- [0.9 README](https://github.com/rails-api/active_model_serializers/blob/0-9-stable/README.md).
6
-
7
- The original design is also available [here](https://github.com/rails-api/active_model_serializers/blob/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e/README.textile).
8
-
9
- # ARCHITECTURE
10
-
11
- An **`ActiveModel::Serializer`** wraps a [serializable resource](https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/serialization.rb)
12
- and exposes an `attributes` method, among a few others.
13
- It allows you to specify which attributes and associations should be represented in the serializatation of the resource.
14
- It requires an adapter to transform its attributes into a JSON document; it cannot be serialized itself.
15
- It may be useful to think of it as a
16
- [presenter](http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
17
-
18
- The **`ActiveModel::ArraySerializer`** represent a collection of resources as serializers
19
- and, if there is no serializer, primitives.
20
-
21
- The **`ActiveModel::Adapter`** describes the structure of the JSON document generated from a
22
- serializer. For example, the `Attributes` example represents each serializer as its
23
- unmodified attributes. The `JsonApi` adapter represents the serializer as a [JSON
24
- API](http://jsonapi.org/) document.
25
-
26
- The **`ActiveModelSerializers::SerializableResource`** acts to coordinate the serializer(s) and adapter
27
- to an object that responds to `to_json`, and `as_json`. It is used in the controller to
28
- encapsulate the serialization resource when rendered. However, it can also be used on its own
29
- to serialize a resource outside of a controller, as well.
30
-
31
- ## Primitive handling
32
-
33
- Definitions: A primitive is usually a String or Array. There is no serializer
34
- defined for them; they will be serialized when the resource is converted to JSON (`as_json` or
35
- `to_json`). (The below also applies for any object with no serializer.)
36
-
37
- ActiveModelSerializers doesn't handle primitives passed to `render json:` at all.
38
-
39
- However, when a primitive value is an attribute or in a collection,
40
- it is not modified.
41
-
42
- Internally, if no serializer can be found in the controller, the resource is not decorated by
43
- ActiveModelSerializers.
44
-
45
- If the collection serializer (ArraySerializer) cannot
46
- identify a serializer for a resource in its collection, it raises [`NoSerializerError`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128)
47
- which is rescued in `ActiveModel::Serializer::Reflection#build_association` which sets
48
- the association value directly:
49
-
50
- ```ruby
51
- reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
52
- ```
53
-
54
- (which is called by the adapter as `serializer.associations(*)`.)
55
-
56
- ## How options are parsed
57
-
58
- High-level overview:
59
-
60
- - For a collection
61
- - `:serializer` specifies the collection serializer and
62
- - `:each_serializer` specifies the serializer for each resource in the collection.
63
- - For a single resource, the `:serializer` option is the resource serializer.
64
- - Options are partitioned in serializer options and adapter options. Keys for adapter options are specified by
65
- [`ADAPTER_OPTION_KEYS`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/serializable_resource.rb#L5).
66
- The remaining options are serializer options.
67
-
68
- Details:
69
-
70
- 1. **ActionController::Serialization**
71
- 1. `serializable_resource = ActiveModelSerializers::SerializableResource.new(resource, options)`
72
- 1. `options` are partitioned into `adapter_opts` and everything else (`serializer_opts`).
73
- The `adapter_opts` keys are defined in `ActiveModelSerializers::SerializableResource::ADAPTER_OPTION_KEYS`.
74
- 1. **ActiveModelSerializers::SerializableResource**
75
- 1. `if serializable_resource.serializer?` (there is a serializer for the resource, and an adapter is used.)
76
- - Where `serializer?` is `use_adapter? && !!(serializer)`
77
- - Where `use_adapter?`: 'True when no explicit adapter given, or explicit value is truthy (non-nil);
78
- False when explicit adapter is falsy (nil or false)'
79
- - Where `serializer`:
80
- 1. from explicit `:serializer` option, else
81
- 2. implicitly from resource `ActiveModel::Serializer.serializer_for(resource)`
82
- 1. A side-effect of checking `serializer` is:
83
- - The `:serializer` option is removed from the serializer_opts hash
84
- - If the `:each_serializer` option is present, it is removed from the serializer_opts hash and set as the `:serializer` option
85
- 1. The serializer and adapter are created as
86
- 1. `serializer_instance = serializer.new(resource, serializer_opts)`
87
- 2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
88
- 1. **ActiveModel::Serializer::ArraySerializer#new**
89
- 1. If the `serializer_instance` was a `ArraySerializer` and the `:serializer` serializer_opts
90
- is present, then [that serializer is passed into each resource](https://github.com/rails-api/active_model_serializers/blob/a54d237e2828fe6bab1ea5dfe6360d4ecc8214cd/lib/active_model/serializer/array_serializer.rb#L14-L16).
91
- 1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
92
- resource as defined by the serializer.
93
-
94
- ## What does a 'serializable resource' look like?
95
-
96
- - An `ActiveRecord::Base` object.
97
- - Any Ruby object that passes the
98
- [Lint](http://www.rubydoc.info/github/rails-api/active_model_serializers/ActiveModel/Serializer/Lint/Tests)
99
- [code](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer/lint.rb).
100
-
101
- ActiveModelSerializers provides a
102
- [`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb),
103
- which is a simple serializable PORO (Plain-Old Ruby Object).
104
-
105
- ActiveModelSerializers::Model may be used either as a template, or in production code.
106
-
107
- ```ruby
108
- class MyModel < ActiveModelSerializers::Model
109
- attr_accessor :id, :name, :level
110
- end
111
- ```
112
-
113
- The default serializer for `MyModel` would be `MyModelSerializer` whether MyModel is an
114
- ActiveRecord::Base object or not.
115
-
116
- Outside of the controller the rules are **exactly** the same as for records. For example:
117
-
118
- ```ruby
119
- render json: MyModel.new(level: 'awesome'), adapter: :json
120
- ```
121
-
122
- would be serialized the same as
123
-
124
- ```ruby
125
- ActiveModelSerializers::SerializableResource.new(MyModel.new(level: 'awesome'), adapter: :json).as_json
126
- ```
@@ -1,100 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- # Defines an association in the object should be rendered.
4
- #
5
- # The serializer object should implement the association name
6
- # as a method which should return an array when invoked. If a method
7
- # with the association name does not exist, the association name is
8
- # dispatched to the serialized object.
9
- #
10
- module Associations
11
- extend ActiveSupport::Concern
12
-
13
- DEFAULT_INCLUDE_TREE = ActiveModel::Serializer::IncludeTree.from_string('*')
14
-
15
- included do
16
- with_options instance_writer: false, instance_reader: true do |serializer|
17
- serializer.class_attribute :_reflections
18
- self._reflections ||= []
19
- end
20
-
21
- extend ActiveSupport::Autoload
22
- autoload :Association
23
- autoload :Reflection
24
- autoload :SingularReflection
25
- autoload :CollectionReflection
26
- autoload :BelongsToReflection
27
- autoload :HasOneReflection
28
- autoload :HasManyReflection
29
- end
30
-
31
- module ClassMethods
32
- def inherited(base)
33
- super
34
- base._reflections = _reflections.dup
35
- end
36
-
37
- # @param [Symbol] name of the association
38
- # @param [Hash<Symbol => any>] options for the reflection
39
- # @return [void]
40
- #
41
- # @example
42
- # has_many :comments, serializer: CommentSummarySerializer
43
- #
44
- def has_many(name, options = {}, &block)
45
- associate(HasManyReflection.new(name, options, block))
46
- end
47
-
48
- # @param [Symbol] name of the association
49
- # @param [Hash<Symbol => any>] options for the reflection
50
- # @return [void]
51
- #
52
- # @example
53
- # belongs_to :author, serializer: AuthorSerializer
54
- #
55
- def belongs_to(name, options = {}, &block)
56
- associate(BelongsToReflection.new(name, options, block))
57
- end
58
-
59
- # @param [Symbol] name of the association
60
- # @param [Hash<Symbol => any>] options for the reflection
61
- # @return [void]
62
- #
63
- # @example
64
- # has_one :author, serializer: AuthorSerializer
65
- #
66
- def has_one(name, options = {}, &block)
67
- associate(HasOneReflection.new(name, options, block))
68
- end
69
-
70
- private
71
-
72
- # Add reflection and define {name} accessor.
73
- # @param [ActiveModel::Serializer::Reflection] reflection
74
- # @return [void]
75
- #
76
- # @api private
77
- #
78
- def associate(reflection)
79
- self._reflections << reflection
80
- end
81
- end
82
-
83
- # @param [IncludeTree] include_tree (defaults to all associations when not provided)
84
- # @return [Enumerator<Association>]
85
- #
86
- def associations(include_tree = DEFAULT_INCLUDE_TREE)
87
- return unless object
88
-
89
- Enumerator.new do |y|
90
- self.class._reflections.each do |reflection|
91
- next if reflection.excluded?(self)
92
- key = reflection.options.fetch(:key, reflection.name)
93
- next unless include_tree.key?(key)
94
- y.yield reflection.build_association(self, instance_options)
95
- end
96
- end
97
- end
98
- end
99
- end
100
- end
@@ -1,82 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- module Attributes
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- with_options instance_writer: false, instance_reader: false do |serializer|
8
- serializer.class_attribute :_attributes_data # @api private
9
- self._attributes_data ||= {}
10
- end
11
-
12
- extend ActiveSupport::Autoload
13
- autoload :Attribute
14
-
15
- # Return the +attributes+ of +object+ as presented
16
- # by the serializer.
17
- def attributes(requested_attrs = nil, reload = false)
18
- @attributes = nil if reload
19
- @attributes ||= self.class._attributes_data.each_with_object({}) do |(key, attr), hash|
20
- next if attr.excluded?(self)
21
- next unless requested_attrs.nil? || requested_attrs.include?(key)
22
- hash[key] = attr.value(self)
23
- end
24
- end
25
- end
26
-
27
- module ClassMethods
28
- def inherited(base)
29
- super
30
- base._attributes_data = _attributes_data.dup
31
- end
32
-
33
- # @example
34
- # class AdminAuthorSerializer < ActiveModel::Serializer
35
- # attributes :id, :name, :recent_edits
36
- def attributes(*attrs)
37
- attrs = attrs.first if attrs.first.class == Array
38
-
39
- attrs.each do |attr|
40
- attribute(attr)
41
- end
42
- end
43
-
44
- # @example
45
- # class AdminAuthorSerializer < ActiveModel::Serializer
46
- # attributes :id, :recent_edits
47
- # attribute :name, key: :title
48
- #
49
- # attribute :full_name do
50
- # "#{object.first_name} #{object.last_name}"
51
- # end
52
- #
53
- # def recent_edits
54
- # object.edits.last(5)
55
- # end
56
- def attribute(attr, options = {}, &block)
57
- key = options.fetch(:key, attr)
58
- _attributes_data[key] = Attribute.new(attr, options, block)
59
- end
60
-
61
- # @api private
62
- # keys of attributes
63
- # @see Serializer::attribute
64
- def _attributes
65
- _attributes_data.keys
66
- end
67
-
68
- # @api private
69
- # maps attribute value to explict key name
70
- # @see Serializer::attribute
71
- # @see FragmentCache#fragment_serializer
72
- def _attributes_keys
73
- _attributes_data
74
- .each_with_object({}) do |(key, attr), hash|
75
- next if key == attr.name
76
- hash[attr.name] = { key: key }
77
- end
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,7 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- # @api private
4
- class CollectionReflection < Reflection
5
- end
6
- end
7
- end
@@ -1,35 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- module Configuration
4
- include ActiveSupport::Configurable
5
- extend ActiveSupport::Concern
6
-
7
- # Configuration options may also be set in
8
- # Serializers and Adapters
9
- included do |base|
10
- config = base.config
11
- config.collection_serializer = ActiveModel::Serializer::CollectionSerializer
12
- config.serializer_lookup_enabled = true
13
-
14
- def config.array_serializer=(collection_serializer)
15
- self.collection_serializer = collection_serializer
16
- end
17
-
18
- def config.array_serializer
19
- collection_serializer
20
- end
21
-
22
- config.adapter = :attributes
23
- config.jsonapi_resource_type = :plural
24
- config.jsonapi_version = '1.0'
25
- config.jsonapi_toplevel_meta = {}
26
- # Make JSON API top-level jsonapi member opt-in
27
- # ref: http://jsonapi.org/format/#document-top-level
28
- config.jsonapi_include_toplevel_object = false
29
- config.key_transform = nil
30
-
31
- config.schema_path = 'test/support/schemas'
32
- end
33
- end
34
- end
35
- end
@@ -1,111 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- # TODO: description of this class, and overview of how it's used
4
- class IncludeTree
5
- module Parsing
6
- module_function
7
-
8
- # Translates a comma separated list of dot separated paths (JSON API format) into a Hash.
9
- #
10
- # @example
11
- # `'posts.author, posts.comments.upvotes, posts.comments.author'`
12
- #
13
- # would become
14
- #
15
- # `{ posts: { author: {}, comments: { author: {}, upvotes: {} } } }`.
16
- #
17
- # @param [String] included
18
- # @return [Hash] a Hash representing the same tree structure
19
- def include_string_to_hash(included)
20
- # TODO: Needs comment walking through the process of what all this is doing.
21
- included.delete(' ').split(',').reduce({}) do |hash, path|
22
- include_tree = path.split('.').reverse_each.reduce({}) { |a, e| { e.to_sym => a } }
23
- hash.deep_merge!(include_tree)
24
- end
25
- end
26
-
27
- # Translates the arguments passed to the include option into a Hash. The format can be either
28
- # a String (see #include_string_to_hash), an Array of Symbols and Hashes, or a mix of both.
29
- #
30
- # @example
31
- # `posts: [:author, comments: [:author, :upvotes]]`
32
- #
33
- # would become
34
- #
35
- # `{ posts: { author: {}, comments: { author: {}, upvotes: {} } } }`.
36
- #
37
- # @example
38
- # `[:author, :comments => [:author]]`
39
- #
40
- # would become
41
- #
42
- # `{:author => {}, :comments => { author: {} } }`
43
- #
44
- # @param [Symbol, Hash, Array, String] included
45
- # @return [Hash] a Hash representing the same tree structure
46
- def include_args_to_hash(included)
47
- case included
48
- when Symbol
49
- { included => {} }
50
- when Hash
51
- included.each_with_object({}) do |(key, value), hash|
52
- hash[key] = include_args_to_hash(value)
53
- end
54
- when Array
55
- included.reduce({}) { |a, e| a.deep_merge!(include_args_to_hash(e)) }
56
- when String
57
- include_string_to_hash(included)
58
- else
59
- {}
60
- end
61
- end
62
- end
63
-
64
- # Builds an IncludeTree from a comma separated list of dot separated paths (JSON API format).
65
- # @example `'posts.author, posts.comments.upvotes, posts.comments.author'`
66
- #
67
- # @param [String] included
68
- # @return [IncludeTree]
69
- #
70
- def self.from_string(included)
71
- new(Parsing.include_string_to_hash(included))
72
- end
73
-
74
- # Translates the arguments passed to the include option into an IncludeTree.
75
- # The format can be either a String (see #from_string), an Array of Symbols and Hashes, or a mix of both.
76
- # @example `posts: [:author, comments: [:author, :upvotes]]`
77
- #
78
- # @param [Symbol, Hash, Array, String] included
79
- # @return [IncludeTree]
80
- #
81
- def self.from_include_args(included)
82
- return included if included.is_a?(IncludeTree)
83
-
84
- new(Parsing.include_args_to_hash(included))
85
- end
86
-
87
- # @param [Hash] hash
88
- def initialize(hash = {})
89
- @hash = hash
90
- end
91
-
92
- def key?(key)
93
- @hash.key?(key) || @hash.key?(:*) || @hash.key?(:**)
94
- end
95
-
96
- def [](key)
97
- # TODO(beauby): Adopt a lazy caching strategy for generating subtrees.
98
- case
99
- when @hash.key?(key)
100
- self.class.new(@hash[key])
101
- when @hash.key?(:*)
102
- self.class.new(@hash[:*])
103
- when @hash.key?(:**)
104
- self.class.new(:** => {})
105
- else
106
- nil
107
- end
108
- end
109
- end
110
- end
111
- end
@@ -1,35 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- module Links
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- with_options instance_writer: false, instance_reader: true do |serializer|
8
- serializer.class_attribute :_links # @api private
9
- self._links ||= {}
10
- end
11
-
12
- extend ActiveSupport::Autoload
13
- end
14
-
15
- module ClassMethods
16
- def inherited(base)
17
- super
18
- base._links = _links.dup
19
- end
20
-
21
- # Define a link on a serializer.
22
- # @example
23
- # link(:self) { resource_url(object) }
24
- # @example
25
- # link(:self) { "http://example.com/resource/#{object.id}" }
26
- # @example
27
- # link :resource, "http://example.com/resource"
28
- #
29
- def link(name, value = nil, &block)
30
- _links[name] = block || value
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,29 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- module Meta
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- with_options instance_writer: false, instance_reader: true do |serializer|
8
- serializer.class_attribute :_meta # @api private
9
- end
10
-
11
- extend ActiveSupport::Autoload
12
- end
13
-
14
- module ClassMethods
15
- # Set the JSON API meta attribute of a serializer.
16
- # @example
17
- # class AdminAuthorSerializer < ActiveModel::Serializer
18
- # meta { stuff: 'value' }
19
- # @example
20
- # meta do
21
- # { comment_count: object.comments.count }
22
- # end
23
- def meta(value = nil, &block)
24
- self._meta = block || value
25
- end
26
- end
27
- end
28
- end
29
- end