active_model_serializers 0.10.0.rc3 → 0.10.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +37 -33
  4. data/.rubocop_todo.yml +13 -88
  5. data/.simplecov +23 -11
  6. data/.travis.yml +17 -12
  7. data/CHANGELOG.md +417 -12
  8. data/CONTRIBUTING.md +206 -17
  9. data/Gemfile +12 -11
  10. data/README.md +78 -286
  11. data/Rakefile +44 -8
  12. data/active_model_serializers.gemspec +9 -1
  13. data/appveyor.yml +6 -4
  14. data/docs/ARCHITECTURE.md +120 -0
  15. data/docs/DESIGN.textile +8 -0
  16. data/docs/README.md +21 -15
  17. data/docs/general/adapters.md +79 -27
  18. data/docs/general/caching.md +52 -0
  19. data/docs/general/configuration_options.md +18 -2
  20. data/docs/general/getting_started.md +44 -19
  21. data/docs/general/instrumentation.md +40 -0
  22. data/docs/general/logging.md +14 -0
  23. data/docs/general/rendering.md +153 -0
  24. data/docs/general/serializers.md +207 -0
  25. data/docs/how-open-source-maintained.jpg +0 -0
  26. data/docs/howto/add_pagination_links.md +16 -7
  27. data/docs/howto/add_root_key.md +3 -3
  28. data/docs/howto/outside_controller_use.md +25 -9
  29. data/docs/howto/test.md +152 -0
  30. data/docs/integrations/ember-and-json-api.md +112 -0
  31. data/docs/integrations/grape.md +19 -0
  32. data/docs/jsonapi/schema.md +140 -0
  33. data/docs/jsonapi/schema/schema.json +366 -0
  34. data/lib/action_controller/serialization.rb +13 -9
  35. data/lib/active_model/serializable_resource.rb +9 -7
  36. data/lib/active_model/serializer.rb +93 -129
  37. data/lib/active_model/serializer/adapter.rb +37 -105
  38. data/lib/active_model/serializer/adapter/attributes.rb +66 -0
  39. data/lib/active_model/serializer/adapter/base.rb +58 -0
  40. data/lib/active_model/serializer/adapter/cached_serializer.rb +45 -0
  41. data/lib/active_model/serializer/adapter/fragment_cache.rb +43 -7
  42. data/lib/active_model/serializer/adapter/json.rb +11 -37
  43. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +9 -1
  44. data/lib/active_model/serializer/adapter/json_api.rb +127 -62
  45. data/lib/active_model/serializer/adapter/json_api/deserialization.rb +207 -0
  46. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +9 -1
  47. data/lib/active_model/serializer/adapter/json_api/link.rb +44 -0
  48. data/lib/active_model/serializer/adapter/json_api/pagination_links.rb +12 -4
  49. data/lib/active_model/serializer/adapter/null.rb +7 -1
  50. data/lib/active_model/serializer/array_serializer.rb +6 -37
  51. data/lib/active_model/serializer/associations.rb +21 -18
  52. data/lib/active_model/serializer/attribute.rb +25 -0
  53. data/lib/active_model/serializer/attributes.rb +82 -0
  54. data/lib/active_model/serializer/caching.rb +100 -0
  55. data/lib/active_model/serializer/collection_serializer.rb +47 -0
  56. data/lib/active_model/serializer/configuration.rb +17 -3
  57. data/lib/active_model/serializer/field.rb +56 -0
  58. data/lib/active_model/serializer/fieldset.rb +9 -18
  59. data/lib/active_model/serializer/include_tree.rb +111 -0
  60. data/lib/active_model/serializer/links.rb +33 -0
  61. data/lib/active_model/serializer/lint.rb +16 -3
  62. data/lib/active_model/serializer/reflection.rb +25 -8
  63. data/lib/active_model/serializer/type.rb +25 -0
  64. data/lib/active_model/serializer/version.rb +1 -1
  65. data/lib/active_model_serializers.rb +16 -26
  66. data/lib/active_model_serializers/callbacks.rb +55 -0
  67. data/lib/active_model_serializers/deserialization.rb +13 -0
  68. data/lib/active_model_serializers/logging.rb +119 -0
  69. data/lib/active_model_serializers/model.rb +39 -0
  70. data/lib/active_model_serializers/railtie.rb +38 -0
  71. data/lib/active_model_serializers/serialization_context.rb +10 -0
  72. data/lib/active_model_serializers/test.rb +7 -0
  73. data/lib/active_model_serializers/test/schema.rb +103 -0
  74. data/lib/active_model_serializers/test/serializer.rb +125 -0
  75. data/lib/generators/{serializer → rails}/USAGE +1 -1
  76. data/lib/generators/{serializer → rails}/resource_override.rb +1 -3
  77. data/lib/generators/{serializer → rails}/serializer_generator.rb +2 -3
  78. data/lib/generators/{serializer → rails}/templates/serializer.rb.erb +0 -0
  79. data/lib/grape/active_model_serializers.rb +14 -0
  80. data/lib/grape/formatters/active_model_serializers.rb +15 -0
  81. data/lib/grape/helpers/active_model_serializers.rb +16 -0
  82. data/test/action_controller/adapter_selector_test.rb +1 -1
  83. data/test/action_controller/json/include_test.rb +167 -0
  84. data/test/action_controller/json_api/deserialization_test.rb +59 -0
  85. data/test/action_controller/json_api/linked_test.rb +20 -3
  86. data/test/action_controller/json_api/pagination_test.rb +7 -7
  87. data/test/action_controller/serialization_scope_name_test.rb +8 -12
  88. data/test/action_controller/serialization_test.rb +44 -29
  89. data/test/active_model_serializers/logging_test.rb +77 -0
  90. data/test/active_model_serializers/model_test.rb +9 -0
  91. data/test/active_model_serializers/railtie_test_isolated.rb +57 -0
  92. data/test/active_model_serializers/serialization_context_test.rb +18 -0
  93. data/test/active_model_serializers/test/schema_test.rb +128 -0
  94. data/test/active_model_serializers/test/serializer_test.rb +63 -0
  95. data/test/active_record_test.rb +1 -1
  96. data/test/adapter/fragment_cache_test.rb +3 -2
  97. data/test/adapter/json/belongs_to_test.rb +2 -2
  98. data/test/adapter/json/collection_test.rb +15 -5
  99. data/test/adapter/json/has_many_test.rb +3 -3
  100. data/test/adapter/json_api/belongs_to_test.rb +3 -3
  101. data/test/adapter/json_api/collection_test.rb +8 -6
  102. data/test/adapter/json_api/fields_test.rb +89 -0
  103. data/test/adapter/json_api/has_many_embed_ids_test.rb +2 -2
  104. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +2 -2
  105. data/test/adapter/json_api/has_many_test.rb +3 -3
  106. data/test/adapter/json_api/has_one_test.rb +2 -2
  107. data/test/adapter/json_api/json_api_test.rb +2 -2
  108. data/test/adapter/json_api/linked_test.rb +116 -5
  109. data/test/adapter/json_api/links_test.rb +68 -0
  110. data/test/adapter/json_api/pagination_links_test.rb +4 -4
  111. data/test/adapter/json_api/parse_test.rb +139 -0
  112. data/test/adapter/json_api/resource_type_config_test.rb +27 -15
  113. data/test/adapter/json_api/toplevel_jsonapi_test.rb +84 -0
  114. data/test/adapter/json_test.rb +2 -2
  115. data/test/adapter/null_test.rb +2 -2
  116. data/test/adapter_test.rb +3 -3
  117. data/test/array_serializer_test.rb +30 -93
  118. data/test/collection_serializer_test.rb +100 -0
  119. data/test/fixtures/poro.rb +19 -51
  120. data/test/generators/scaffold_controller_generator_test.rb +1 -0
  121. data/test/generators/serializer_generator_test.rb +2 -1
  122. data/test/grape_test.rb +82 -0
  123. data/test/include_tree/from_include_args_test.rb +26 -0
  124. data/test/include_tree/from_string_test.rb +94 -0
  125. data/test/include_tree/include_args_to_hash_test.rb +64 -0
  126. data/test/lint_test.rb +4 -1
  127. data/test/logger_test.rb +2 -2
  128. data/test/poro_test.rb +1 -1
  129. data/test/serializable_resource_test.rb +1 -1
  130. data/test/serializers/adapter_for_test.rb +24 -28
  131. data/test/serializers/association_macros_test.rb +1 -1
  132. data/test/serializers/associations_test.rb +143 -26
  133. data/test/serializers/attribute_test.rb +64 -3
  134. data/test/serializers/attributes_test.rb +1 -6
  135. data/test/serializers/cache_test.rb +46 -2
  136. data/test/serializers/configuration_test.rb +20 -3
  137. data/test/serializers/fieldset_test.rb +5 -16
  138. data/test/serializers/meta_test.rb +38 -29
  139. data/test/serializers/options_test.rb +1 -1
  140. data/test/serializers/root_test.rb +1 -1
  141. data/test/serializers/serializer_for_test.rb +78 -9
  142. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  143. data/test/support/isolated_unit.rb +77 -0
  144. data/test/support/rails5_shims.rb +29 -0
  145. data/test/support/rails_app.rb +7 -3
  146. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  147. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
  148. data/test/support/schemas/custom/show.json +7 -0
  149. data/test/support/schemas/hyper_schema.json +93 -0
  150. data/test/support/schemas/render_using_json_api.json +43 -0
  151. data/test/support/schemas/simple_json_pointers.json +10 -0
  152. data/test/support/serialization_testing.rb +46 -6
  153. data/test/support/test_case.rb +14 -0
  154. data/test/test_helper.rb +21 -14
  155. metadata +160 -16
  156. data/lib/active_model/serializer/adapter/flatten_json.rb +0 -12
  157. data/lib/active_model/serializer/railtie.rb +0 -15
  158. data/lib/active_model/serializer/utils.rb +0 -35
  159. data/lib/tasks/rubocop.rake +0 -0
  160. data/test/capture_warnings.rb +0 -65
  161. data/test/utils/include_args_to_hash_test.rb +0 -79
@@ -0,0 +1,207 @@
1
+ [Back to Guides](../README.md)
2
+
3
+ # Serializers
4
+
5
+ Given a serializer class:
6
+
7
+ ```ruby
8
+ class SomeSerializer < ActiveModel::Serializer
9
+ end
10
+ ```
11
+
12
+ The following methods may be defined in it:
13
+
14
+ ### Attributes
15
+
16
+ #### ::attributes
17
+
18
+ Serialization of the resource `title` and `body`
19
+
20
+ | In Serializer | #attributes |
21
+ |---------------------------- |-------------|
22
+ | `attributes :title, :body` | `{ title: 'Some Title', body: 'Some Body' }`
23
+ | `attributes :title, :body`<br>`def body "Special #{object.body}" end` | `{ title: 'Some Title', body: 'Special Some Body' }`
24
+
25
+
26
+ #### ::attribute
27
+
28
+ Serialization of the resource `title`
29
+
30
+ | In Serializer | #attributes |
31
+ |---------------------------- |-------------|
32
+ | `attribute :title` | `{ title: 'Some Title' } `
33
+ | `attribute :title, key: :name` | `{ name: 'Some Title' } `
34
+ | `attribute :title { 'A Different Title'}` | `{ title: 'A Different Title' } `
35
+ | `attribute :title`<br>`def title 'A Different Title' end` | `{ title: 'A Different Title' }`
36
+
37
+ [PR please for conditional attributes:)](https://github.com/rails-api/active_model_serializers/pull/1403)
38
+
39
+ ### Associations
40
+
41
+ #### ::has_one
42
+
43
+ e.g.
44
+
45
+ ```ruby
46
+ has_one :bio
47
+ has_one :blog, key: :site
48
+ has_one :maker, virtual_value: { id: 1 }
49
+ ```
50
+
51
+ #### ::has_many
52
+
53
+ e.g.
54
+
55
+ ```ruby
56
+ has_many :comments
57
+ has_many :comments, key: :reviews
58
+ has_many :comments, serializer: CommentPreviewSerializer
59
+ has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]
60
+ has_many :comments, key: :last_comments do
61
+ last(1)
62
+ end
63
+ ```
64
+
65
+ #### ::belongs_to
66
+
67
+ e.g.
68
+
69
+ ```ruby
70
+ belongs_to :author, serializer: AuthorPreviewSerializer
71
+ belongs_to :author, key: :writer
72
+ belongs_to :post
73
+ belongs_to :blog
74
+ def blog
75
+ Blog.new(id: 999, name: 'Custom blog')
76
+ end
77
+ ```
78
+
79
+ ### Caching
80
+
81
+ #### ::cache
82
+
83
+ e.g.
84
+
85
+ ```ruby
86
+ cache key: 'post', expires_in: 0.1, skip_digest: true
87
+ cache expires_in: 1.day, skip_digest: true
88
+ cache key: 'writer', skip_digest: true
89
+ cache only: [:name], skip_digest: true
90
+ cache except: [:content], skip_digest: true
91
+ cache key: 'blog'
92
+ cache only: [:id]
93
+ ```
94
+
95
+ #### #cache_key
96
+
97
+ e.g.
98
+
99
+ ```ruby
100
+ # Uses a custom non-time-based cache key
101
+ def cache_key
102
+ "#{self.class.name.downcase}/#{self.id}"
103
+ end
104
+ ```
105
+
106
+ ### Other
107
+
108
+ #### ::type
109
+
110
+ e.g.
111
+
112
+ ```ruby
113
+ class UserProfileSerializer < ActiveModel::Serializer
114
+ type 'profile'
115
+ end
116
+ ```
117
+
118
+ #### ::link
119
+
120
+ e.g.
121
+
122
+ ```ruby
123
+ link :other, 'https://example.com/resource'
124
+ link :self do
125
+ href "https://example.com/link_author/#{object.id}"
126
+ end
127
+ ```
128
+
129
+ #### #object
130
+
131
+ The object being serialized.
132
+
133
+ #### #root
134
+
135
+ PR please :)
136
+
137
+ #### #scope
138
+
139
+ PR please :)
140
+
141
+ #### #read_attribute_for_serialization(key)
142
+
143
+ The serialized value for a given key. e.g. `read_attribute_for_serialization(:title) #=> 'Hello World'`
144
+
145
+ #### #links
146
+
147
+ PR please :)
148
+
149
+ #### #json_key
150
+
151
+ PR please :)
152
+
153
+ ## Examples
154
+
155
+ Given two models, a `Post(title: string, body: text)` and a
156
+ `Comment(name: string, body: text, post_id: integer)`, you will have two
157
+ serializers:
158
+
159
+ ```ruby
160
+ class PostSerializer < ActiveModel::Serializer
161
+ cache key: 'posts', expires_in: 3.hours
162
+ attributes :title, :body
163
+
164
+ has_many :comments
165
+ end
166
+ ```
167
+
168
+ and
169
+
170
+ ```ruby
171
+ class CommentSerializer < ActiveModel::Serializer
172
+ attributes :name, :body
173
+
174
+ belongs_to :post
175
+ end
176
+ ```
177
+
178
+ Generally speaking, you, as a user of ActiveModelSerializers, will write (or generate) these
179
+ serializer classes.
180
+
181
+ ## More Info
182
+
183
+ For more information, see [the Serializer class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer.rb)
184
+
185
+ ## Overriding association methods
186
+
187
+ To override an association, call `has_many`, `has_one` or `belongs_to` with a block:
188
+
189
+ ```ruby
190
+ class PostSerializer < ActiveModel::Serializer
191
+ has_many :comments do
192
+ object.comments.active
193
+ end
194
+ end
195
+ ```
196
+
197
+ ## Overriding attribute methods
198
+
199
+ To override an attribute, call `attribute` with a block:
200
+
201
+ ```ruby
202
+ class PostSerializer < ActiveModel::Serializer
203
+ attribute :body do
204
+ object.body.downcase
205
+ end
206
+ end
207
+ ```
@@ -1,12 +1,21 @@
1
+ [Back to Guides](../README.md)
2
+
1
3
  # How to add pagination links
2
4
 
3
- ### JSON-API adapter
5
+ ### JSON API adapter
6
+
7
+ Pagination links will be included in your response automatically as long as
8
+ the resource is paginated and if you are using the ```JsonApi``` adapter.
4
9
 
5
- Pagination links will be included in your response automatically as long as the resource is paginated and if you are using a ```JSON-API``` adapter.
10
+ If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari)
11
+ or [WillPaginate](https://github.com/mislav/will_paginate).
6
12
 
7
- If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
13
+ Although the others adapters does not have this feature, it is possible to
14
+ implement pagination links to `JSON` adapter. For more information about it,
15
+ please see in our docs
8
16
 
9
17
  ###### Kaminari examples
18
+
10
19
  ```ruby
11
20
  #array
12
21
  @posts = Kaminari.paginate_array([1, 2, 3]).page(3).per(1)
@@ -30,7 +39,7 @@ render json: @posts
30
39
  ```
31
40
 
32
41
  ```ruby
33
- ActiveModel::Serializer.config.adapter = :json_api
42
+ ActiveModelSerializers.config.adapter = :json_api
34
43
  ```
35
44
 
36
45
  ex:
@@ -58,7 +67,7 @@ ex:
58
67
  }
59
68
  ```
60
69
 
61
- AMS pagination relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
70
+ ActiveModelSerializers pagination relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
62
71
 
63
72
 
64
73
  ### JSON adapter
@@ -72,7 +81,7 @@ render json: @posts, serializer: PaginatedSerializer, each_serializer: PostPrevi
72
81
 
73
82
  And then, you could do something like the following class.
74
83
  ```ruby
75
- class PaginatedSerializer < ActiveModel::Serializer::ArraySerializer
84
+ class PaginatedSerializer < ActiveModel::Serializer::CollectionSerializer
76
85
  def initialize(object, options={})
77
86
  meta_key = options[:meta_key] || :meta
78
87
  options[meta_key] ||= {}
@@ -107,6 +116,6 @@ ex.
107
116
  }
108
117
  ```
109
118
 
110
- ### FlattenJSON adapter
119
+ ### Attributes adapter
111
120
 
112
121
  This adapter does not allow us to use `meta` key, due to that it is not possible to add pagination links.
@@ -1,6 +1,6 @@
1
1
  # How to add root key
2
2
 
3
- Add the root key to your API is quite simple with AMS. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```FlattenJSON``` which doesn't have the root key, so your response is something similar to:
3
+ Add the root key to your API is quite simple with ActiveModelSerializers. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```Attributes``` which doesn't have the root key, so your response is something similar to:
4
4
 
5
5
  ```json
6
6
  {
@@ -13,10 +13,10 @@ Add the root key to your API is quite simple with AMS. The **Adapter** is what d
13
13
  In order to add the root key you need to use the ```JSON``` Adapter, you can change this in an initializer:
14
14
 
15
15
  ```ruby
16
- ActiveModel::Serializer.config.adapter = :json
16
+ ActiveModelSerializers.config.adapter = :json
17
17
  ```
18
18
 
19
- You can also specify a class as adapter, as long as it complies with the AMS adapters interface.
19
+ You can also specify a class as adapter, as long as it complies with the ActiveModelSerializers adapters interface.
20
20
  It will add the root key to all your serialized endpoints.
21
21
 
22
22
  ex:
@@ -1,8 +1,10 @@
1
- ## Using AMS Outside Of A Controller
1
+ [Back to Guides](../README.md)
2
2
 
3
- ### Serializing a resource
3
+ ## Using ActiveModelSerializers Outside Of A Controller
4
4
 
5
- In AMS versions 0.10 or later, serializing resources outside of the controller context is fairly simple:
5
+ ### Serializing a resource
6
+
7
+ In ActiveModelSerializers versions 0.10 or later, serializing resources outside of the controller context is fairly simple:
6
8
 
7
9
  ```ruby
8
10
  # Create our resource
@@ -16,14 +18,14 @@ serializable_resource = ActiveModel::SerializableResource.new(post, options)
16
18
 
17
19
  # Convert your resource into json
18
20
  model_json = serializable_resource.as_json
19
- ```
21
+ ```
20
22
 
21
- ### Retrieving a Resource's Active Model Serializer
23
+ ### Looking up the Serializer for a Resource
22
24
 
23
25
  If you want to retrieve a serializer for a specific resource, you can do the following:
24
26
 
25
27
  ```ruby
26
- # Create our resource
28
+ # Create our resource
27
29
  post = Post.create(title: "Another Example", body: "So much fun.")
28
30
 
29
31
  # Optional options parameters
@@ -33,10 +35,24 @@ options = {}
33
35
  serializer = ActiveModel::Serializer.serializer_for(post, options)
34
36
  ```
35
37
 
36
- You could also retrieve the serializer via:
38
+ You could also retrieve the serializer via:
37
39
 
38
40
  ```ruby
39
- ActiveModel::SerializableResource.new(post, options).serializer
41
+ ActiveModel::SerializableResource.new(post, options).serializer
40
42
  ```
41
43
 
42
- Both approaches will return an instance, if any, of the resource's serializer.
44
+ Both approaches will return an instance, if any, of the resource's serializer.
45
+
46
+ ## Serializing before controller render
47
+
48
+ At times, you might want to use a serializer without rendering it to the view. For those cases, you can create an instance of `ActiveModel::SerializableResource` with
49
+ the resource you want to be serialized and call `.as_json`.
50
+
51
+ ```ruby
52
+ def create
53
+ message = current_user.messages.create!(message_params)
54
+ message_json = ActiveModel::SerializableResource.new(message).as_json
55
+ MessageCreationWorker.perform(message_json)
56
+ head 204
57
+ end
58
+ ```
@@ -0,0 +1,152 @@
1
+ # How to test
2
+
3
+ ## Controller Serializer Usage
4
+
5
+ ActiveModelSerializers provides a `assert_serializer` method to be used on your controller tests to
6
+ assert that a specific serializer was used.
7
+
8
+ ```ruby
9
+ class PostsControllerTest < ActionController::TestCase
10
+ test "should render post serializer" do
11
+ get :index
12
+ assert_serializer "PostSerializer"
13
+ end
14
+ end
15
+ ```
16
+
17
+ See [ActiveModelSerializers::Test::Serializer](../../lib/active_model_serializers/test/serializer.rb)
18
+ for more examples and documentation.
19
+
20
+ ## Serialization against a schema
21
+
22
+ ### Dependencies
23
+
24
+ To use the `assert_response_schema` you need to have the
25
+ [`json_schema`](https://github.com/brandur/json_schema) on your Gemfile. Please
26
+ add it to your Gemfile and run `$ bundle install`.
27
+
28
+ ### Minitest test helpers
29
+
30
+ ActiveModelSerializers provides a `assert_response_schema` method to be used on your controller tests to
31
+ assert the response against a [JSON Schema](http://json-schema.org/). Let's take
32
+ a look in an example.
33
+
34
+ ```ruby
35
+ class PostsController < ApplicationController
36
+ def show
37
+ @post = Post.find(params[:id])
38
+
39
+ render json: @post
40
+ end
41
+ end
42
+ ```
43
+
44
+ To test the `posts#show` response of this controller we need to create a file
45
+ named `test/support/schemas/posts/show.json`. The helper uses a naming convention
46
+ to locate the file.
47
+
48
+ This file is a JSON Schema representation of our response.
49
+
50
+ ```json
51
+ {
52
+ "properties": {
53
+ "title" : { "type" : "string" },
54
+ "content" : { "type" : "string" }
55
+ }
56
+ }
57
+ ```
58
+
59
+ With all in place we can go to our test and use the helper.
60
+
61
+ ```ruby
62
+ class PostsControllerTest < ActionController::TestCase
63
+ test "should render right response" do
64
+ get :index
65
+ assert_response_schema
66
+ end
67
+ end
68
+ ```
69
+
70
+ #### Load a custom schema
71
+
72
+ If we need to use another schema, for example when we have a namespaced API that
73
+ shows the same response, we can pass the path of the schema.
74
+
75
+ ```ruby
76
+ module V1
77
+ class PostsController < ApplicationController
78
+ def show
79
+ @post = Post.find(params[:id])
80
+
81
+ render json: @post
82
+ end
83
+ end
84
+ end
85
+ ```
86
+
87
+ ```ruby
88
+ class V1::PostsControllerTest < ActionController::TestCase
89
+ test "should render right response" do
90
+ get :index
91
+ assert_response_schema('posts/show.json')
92
+ end
93
+ end
94
+ ```
95
+
96
+ #### Change the schema path
97
+
98
+ By default all schemas are created at `test/support/schemas`. If we are using
99
+ RSpec for example we can change this to `spec/support/schemas` defining the
100
+ default schema path in an initializer.
101
+
102
+ ```ruby
103
+ ActiveModelSerializers.config.schema_path = 'spec/support/schemas'
104
+ ```
105
+
106
+ #### Using with the Heroku’s JSON Schema-based tools
107
+
108
+ To use the test helper with the [prmd](https://github.com/interagent/prmd) and
109
+ [committee](https://github.com/interagent/committee).
110
+
111
+ We need to change the schema path to the recommended by prmd:
112
+
113
+ ```ruby
114
+ ActiveModelSerializers.config.schema_path = 'docs/schema/schemata'
115
+ ```
116
+
117
+ We also need to structure our schemata according to Heroku's conventions
118
+ (e.g. including
119
+ [required metadata](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)
120
+ and [links](https://github.com/interagent/prmd/blob/master/docs/schemata.md#links).
121
+
122
+ #### JSON Pointers
123
+
124
+ If we plan to use [JSON
125
+ Pointers](http://spacetelescope.github.io/understanding-json-schema/UnderstandingJSONSchema.pdf) we need to define the `id` attribute on the schema. Example:
126
+
127
+ ```js
128
+ // attributes.json
129
+
130
+ {
131
+ "id": "file://attributes.json#",
132
+ "properties": {
133
+ "name" : { "type" : "string" },
134
+ "description" : { "type" : "string" }
135
+ }
136
+ }
137
+ ```
138
+
139
+ ```js
140
+ // show.json
141
+
142
+ {
143
+ "properties": {
144
+ "name": {
145
+ "$ref": "file://attributes.json#/properties/name"
146
+ },
147
+ "description": {
148
+ "$ref": "file://attributes.json#/properties/description"
149
+ }
150
+ }
151
+ }
152
+ ```