Skip to content

Commit 68c4076

Browse files
committed
[DOCS] Refactor, update, create documentation
1 parent f562449 commit 68c4076

19 files changed

+531
-360
lines changed

README.md

Lines changed: 57 additions & 276 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,25 @@
66

77
_Windows Build Status -_ [![Build status](https://ci.appveyor.com/api/projects/status/x6xdjydutm54gvyt/branch/master?svg=true)](https://ci.appveyor.com/project/joaomdmoura/active-model-serializers/branch/master)
88

9+
# About
10+
911
ActiveModelSerializers brings convention over configuration to your JSON generation.
1012

11-
AMS does this through two components: **serializers** and **adapters**.
13+
ActiveModelSerializers works through two components: **serializers** and **adapters**.
14+
1215
Serializers describe _which_ attributes and relationships should be serialized.
16+
1317
Adapters describe _how_ attributes and relationships should be serialized.
1418

15-
By default AMS will use the **Attributes Adapter**. But we strongly advise you to use **JsonApi Adapter** that follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
16-
Check how to change the adapter in the sections bellow.
19+
SerializableResource co-ordinates the resource, Adapter and Serializer to produce the
20+
resource serialization, which has the `#as_json`, `#to_json` and `#serializable_hash`
21+
methods used by the Rails JSON Renderer. (SerializableResource actually delegates
22+
these methods to the adapter.)
23+
24+
By default ActiveModelSerializers will use the **Attributes Adapter**.
25+
But we strongly advise you to use **JsonApi Adapter**, which
26+
follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
27+
Check how to change the adapter in the sections below.
1728

1829
# Documentation
1930

@@ -24,222 +35,13 @@ Master
2435

2536
# RELEASE CANDIDATE, PLEASE READ
2637

27-
This is the master branch of AMS. It will become the `0.10.0` release when it's
38+
This is the master branch of ActiveModelSerializers. It will become the `0.10.0` release when it's
2839
ready. Currently this is a release candidate. This is **not** backward
2940
compatible with `0.9.0` or `0.8.0`.
3041

3142
`0.10.x` will be based on the `0.8.0` code, but with a more flexible
3243
architecture. We'd love your help. [Learn how you can help here.](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)
3344

34-
## Example
35-
36-
Given two models, a `Post(title: string, body: text)` and a
37-
`Comment(name: string, body: text, post_id: integer)`, you will have two
38-
serializers:
39-
40-
```ruby
41-
class PostSerializer < ActiveModel::Serializer
42-
cache key: 'posts', expires_in: 3.hours
43-
attributes :title, :body
44-
45-
has_many :comments
46-
end
47-
```
48-
49-
and
50-
51-
```ruby
52-
class CommentSerializer < ActiveModel::Serializer
53-
attributes :name, :body
54-
55-
belongs_to :post
56-
end
57-
```
58-
59-
Generally speaking, you as a user of AMS will write (or generate) these
60-
serializer classes. If you want to use a different adapter, such as a JsonApi, you can
61-
change this in an initializer:
62-
63-
```ruby
64-
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
65-
```
66-
67-
or
68-
69-
```ruby
70-
ActiveModel::Serializer.config.adapter = :json_api
71-
```
72-
73-
You won't need to implement an adapter unless you wish to use a new format or
74-
media type with AMS.
75-
76-
If you want to have a root key on your responses you should use the Json adapter, instead of the default Attributes:
77-
78-
```ruby
79-
ActiveModel::Serializer.config.adapter = :json
80-
```
81-
82-
If you would like the key in the outputted JSON to be different from its name in ActiveRecord, you can use the :key option to customize it:
83-
84-
```ruby
85-
class PostSerializer < ActiveModel::Serializer
86-
attributes :id, :body
87-
88-
# look up :subject on the model, but use +title+ in the JSON
89-
attribute :subject, :key => :title
90-
has_many :comments
91-
end
92-
```
93-
94-
In your controllers, when you use `render :json`, Rails will now first search
95-
for a serializer for the object and use it if available.
96-
97-
```ruby
98-
class PostsController < ApplicationController
99-
def show
100-
@post = Post.find(params[:id])
101-
102-
render json: @post
103-
end
104-
end
105-
```
106-
107-
In this case, Rails will look for a serializer named `PostSerializer`, and if
108-
it exists, use it to serialize the `Post`.
109-
110-
### Specify a serializer
111-
112-
If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
113-
114-
#### 1. For a resource:
115-
116-
```ruby
117-
render json: @post, serializer: PostPreviewSerializer
118-
```
119-
120-
#### 2. For an array resource:
121-
122-
```ruby
123-
# Use the default `CollectionSerializer`, which will use `each_serializer` to
124-
# serialize each element
125-
render json: @posts, each_serializer: PostPreviewSerializer
126-
127-
# Or, you can explicitly provide the collection serializer as well
128-
render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
129-
```
130-
131-
### Meta
132-
133-
If you want a `meta` attribute in your response, specify it in the `render`
134-
call:
135-
136-
```ruby
137-
render json: @post, meta: { total: 10 }
138-
```
139-
140-
The key can be customized using `meta_key` option.
141-
142-
```ruby
143-
render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
144-
```
145-
146-
`meta` will only be included in your response if you are using an Adapter that supports `root`,
147-
as JsonAPI and Json adapters, the default adapter (Attributes) doesn't have `root`.
148-
149-
### Using a serializer without `render`
150-
151-
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
152-
the resource you want to be serialized and call `.serializable_hash`.
153-
154-
```ruby
155-
def create
156-
@message = current_user.messages.create!(message_params)
157-
MessageCreationWorker.perform(serialized_message)
158-
head 204
159-
end
160-
161-
def serialized_message
162-
ActiveModel::SerializableResource.new(@message).serializable_hash
163-
end
164-
```
165-
166-
### Overriding association methods
167-
168-
If you want to override any association, you can use:
169-
170-
```ruby
171-
class PostSerializer < ActiveModel::Serializer
172-
attributes :id, :body
173-
174-
has_many :comments
175-
176-
def comments
177-
object.comments.active
178-
end
179-
end
180-
```
181-
182-
### Overriding attribute methods
183-
184-
If you want to override any attribute, you can use:
185-
186-
```ruby
187-
class PostSerializer < ActiveModel::Serializer
188-
attributes :id, :body
189-
190-
has_many :comments
191-
192-
def body
193-
object.body.downcase
194-
end
195-
end
196-
```
197-
198-
### Built in Adapters
199-
200-
#### Attributes
201-
202-
It's the default adapter, it generates a json response without a root key.
203-
Doesn't follow any specific convention.
204-
205-
#### JSON
206-
207-
It also generates a json response but always with a root key. The root key **can't be overridden**, and will be automatically defined accordingly with the objects being serialized.
208-
Doesn't follow any specific convention.
209-
210-
#### JSON API
211-
212-
This adapter follows 1.0 of the format specified in
213-
[jsonapi.org/format](http://jsonapi.org/format). It will include the associated
214-
resources in the `"included"` member when the resource names are included in the
215-
`include` option. Including nested associated resources is also supported.
216-
217-
```ruby
218-
render @posts, include: ['author', 'comments', 'comments.author']
219-
# or
220-
render @posts, include: 'author,comments,comments.author'
221-
```
222-
223-
In addition, two types of wildcards may be used. `*` includes one level of associations, and `**` includes all recursively. These can be combined with other paths.
224-
225-
```ruby
226-
render @posts, include: '**' # or '*' for a single layer
227-
```
228-
229-
The following would render posts and include the author, the author's comments, and every resource referenced by the author's comments (recursively). It could be combined, like above, with other paths in any combination desired.
230-
231-
```ruby
232-
render @posts, include: 'author.comments.**'
233-
```
234-
235-
The JSON API [specifies](http://jsonapi.org/format/#fetching-includes) that the user may supply a parameter specifying which related resources are to be included:
236-
237-
```ruby
238-
render @posts, include: params[:include]
239-
```
240-
241-
This raises some security concerns since the user could pass in `include=**`, so filter the values for `include` appropriately if you decide to support this JSON API feature.
242-
24345
## Installation
24446

24547
Add this line to your application's Gemfile:
@@ -254,6 +56,8 @@ And then execute:
25456
$ bundle
25557
```
25658

59+
*ActiveModelSerializers is already included on Rails >= 5*
60+
25761
## Creating a Serializer
25862

25963
The easiest way to create a new serializer is to generate a new resource, which
@@ -299,91 +103,68 @@ The `has_many`, `has_one`, and `belongs_to` declarations describe relationships
299103
resources. By default, when you serialize a `Post`, you will get its `Comments`
300104
as well.
301105

302-
You may also use the `:serializer` option to specify a custom serializer class, for example:
106+
For more information, see [Serializers](docs/general/serializers.md).
303107

304-
```ruby
305-
has_many :comments, serializer: CommentPreviewSerializer
306-
```
108+
## High-level behavior
109+
110+
See [Getting Started](docs/general/getting_started.md) and [Examples](README.md#examples) for the nuts and bolts:
307111

308-
And you can change the JSON key that the serializer should use for a particular association:
112+
Given a [serializable model](lib/active_model/serializer/lint.rb):
309113

310114
```ruby
311-
has_many :comments, key: :reviews
115+
# either
116+
class SomeResource < ActiveRecord::Base
117+
# columns: title, body
118+
end
119+
# or
120+
class SomeResource < ActiveModelSerializers::Model
121+
attr_accessor :title, :body
122+
end
312123
```
313124

314-
## Pagination
315-
316-
Pagination links will be included in your response automatically as long
317-
as the resource is paginated using [Kaminari](https://github.com/amatsuda/kaminari) or
318-
[WillPaginate](https://github.com/mislav/will_paginate) and
319-
if you are using the ```JsonApi``` adapter.
320-
321-
Although the others adapters does not have this feature, it is possible to
322-
implement pagination links to `JSON` adapter. For more information about it,
323-
please see in our docs [How to add pagination
324-
links](https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md).
325-
326-
## Caching
327-
328-
To cache a serializer, call ```cache``` and pass its options.
329-
The options are the same options of ```ActiveSupport::Cache::Store```, plus
330-
a ```key``` option that will be the prefix of the object cache
331-
on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
332-
333-
The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
334-
335-
**[NOTE] Every object is individually cached.**
336-
337-
**[NOTE] The cache is automatically expired after an object is updated, but it's not deleted.**
125+
And initialized as:
338126

339127
```ruby
340-
cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
128+
resource = SomeResource.new(title: 'ActiveModelSerializers', body: 'Convention over configuration')
341129
```
342130

343-
Take the example bellow:
131+
Given a serializer for the serializable model:
344132

345133
```ruby
346-
class PostSerializer < ActiveModel::Serializer
347-
cache key: 'post', expires_in: 3.hours
348-
attributes :title, :body
349-
350-
has_many :comments
134+
class SomeSerializer < ActiveModel::Serializer
135+
attribute :title, key: :name
136+
attributes :body
351137
end
352138
```
353139

354-
On this example every ```Post``` object will be cached with
355-
the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
356-
but in this case it will be automatically expired after 3 hours.
357-
358-
### Fragment Caching
359-
360-
If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
361-
362-
You can define the attribute by using ```only``` or ```except``` option on cache method.
363-
364-
**[NOTE] Cache serializers will be used at their relationships**
365-
366-
Example:
140+
The model can be serialized as:
367141

368142
```ruby
369-
class PostSerializer < ActiveModel::Serializer
370-
cache key: 'post', expires_in: 3.hours, only: [:title]
371-
attributes :title, :body
372-
373-
has_many :comments
374-
end
143+
options = {}
144+
serialization = SerializableResource.new(resource, options)
145+
serialization.to_json
146+
serialization.as_json
375147
```
376148

377-
## Serializing non-ActiveRecord objects
378-
379-
All serializable resources must pass the ActiveModel::Serializer::Lint::Tests.
149+
SerializableResource delegates to the adapter, which it builds as:
380150

381-
See the ActiveModelSerializers::Model for a base class that implements the full
382-
API for a plain-old Ruby object (PORO).
151+
```ruby
152+
adapter_options = {}
153+
adapter = Adapter.create(serializer, adapter_options)
154+
adapter.to_json
155+
adapter.as_json
156+
adapter.serializable_hash
157+
```
383158

384-
## Hooks
159+
The adapter formats the serializer's attributes and associations (a.k.a. includes):
385160

386-
To run a hook when ActiveModelSerializers is loaded, use `ActiveSupport.on_load(:active_model_serializers) do end`
161+
```ruby
162+
serializer_options = {}
163+
serializer = SomeSerializer.new(resource, serializer_options)
164+
serializer.attributes
165+
serializer.associations
166+
```
167+
See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for more information.
387168

388169
## Getting Help
389170

0 commit comments

Comments
 (0)