Skip to content

Commit b059268

Browse files
committed
Add docs for links
Add docs for links Add docs for links Add docs for links Add controller info Grammar fixing Improve docs
1 parent 1dc2b74 commit b059268

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This is the documentation of ActiveModelSerializers, it's focused on the **0.10.
2424

2525
- [How to add root key](howto/add_root_key.md)
2626
- [How to add pagination links](howto/add_pagination_links.md)
27+
- [How to add relationship links](howto/add_relationship_links.md)
2728
- [Using ActiveModelSerializers Outside Of Controllers](howto/outside_controller_use.md)
2829
- [Testing ActiveModelSerializers](howto/test.md)
2930
- [Passing Arbitrary Options](howto/passing_arbitrary_options.md)
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
[Back to Guides](../README.md)
2+
3+
# How to add relationship links
4+
5+
ActiveModelSerializers offers you many ways to add links in your JSON, depending on your needs.
6+
Usually the most common use case for links is supporting nested resources.
7+
8+
The following examples assume that you don't want to load any data for relationships (`include` param is empty),
9+
specifically the following Rails controller was used for those examples:
10+
11+
```ruby
12+
class Api::V1::UsersController < ApplicationController
13+
def show
14+
render jsonapi: User.find(params[:id]),
15+
serializer: Api::V1::UserSerializer,
16+
include: []
17+
end
18+
```
19+
20+
Bear in mind though that ActiveModelSerializers are [framework-agnostic](../outside_controller_use.md), Rails is just a common example here.
21+
22+
### Links as an attribute of a resource
23+
**This is applicable to JSONAPI, JSON and Attributes adapters**
24+
25+
You can define an attribute in the resource, named `links` and return the
26+
links you want there. An example:
27+
28+
```ruby
29+
class Api::V1::UserSerializer < ActiveModel::Serializer
30+
attributes :id, :name, :links
31+
32+
def links
33+
{
34+
self: api_v1_user_path(object.id),
35+
microposts: api_v1_microposts_path(user_id: object.id)
36+
}
37+
end
38+
end
39+
```
40+
41+
This will resilt in (example is in jsonapi adapter):
42+
```json
43+
{
44+
"data": {
45+
"id": "1",
46+
"type": "users",
47+
"attributes": {
48+
"name": "Example User",
49+
"links": {
50+
"self": "/api/v1/users/1",
51+
"microposts": "/api/v1/microposts?user_id=1"
52+
}
53+
}
54+
}
55+
}
56+
```
57+
58+
59+
### Links as a property of the resource definiton
60+
**This is only applicable to JSONAPI adapter**
61+
62+
You can use the `links` helper method to define the links you need in the resource definition level.
63+
64+
```ruby
65+
class Api::V1::UserSerializer < ActiveModel::Serializer
66+
attributes :id, :name
67+
68+
link(:self) { api_v1_user_path(object.id) }
69+
link(:microposts) { api_v1_microposts_path(user_id: object.id) }
70+
end
71+
```
72+
73+
This will resilt in (example is in jsonapi adapter):
74+
```json
75+
{
76+
"data": {
77+
"id": "1",
78+
"type": "users",
79+
"attributes": {
80+
"name": "Example User"
81+
},
82+
"links": {
83+
"self": "/api/v1/users/1",
84+
"microposts": "/api/v1/microposts?user_id=1"
85+
}
86+
}
87+
}
88+
```
89+
90+
### Links that follow the JSONAPI spec
91+
**This is only applicable to JSONAPI adapter**
92+
93+
If you have a JSONAPI-strict client that you are working with (like `ember-data`)
94+
you need to struct the links inside the relationships. Also the link to fetch the
95+
relationship data must be under the `related` attribute, whereas to manipulate the
96+
relationship (in case of many-to-many relationship) must be under the `self` attribute.
97+
98+
You can find more info in the [spec](http://jsonapi.org/format/#document-resource-object-relationships).
99+
100+
Here is how you can do this:
101+
102+
```ruby
103+
class Api::V1::UserSerializer < ActiveModel::Serializer
104+
attributes :id, :name
105+
106+
has_many :microposts, serializer: Api::V1::MicropostSerializer do
107+
link(:related) { api_v1_microposts_path(user_id: object.id) }
108+
end
109+
110+
#this is needed to avoid n+1, gem core devs are working to remove this necessity
111+
#more on: https://github.com/rails-api/active_model_serializers/issues/1325
112+
def microposts
113+
object.microposts.loaded ? object.microposts : object.microposts.none
114+
end
115+
end
116+
```
117+
118+
This will result in:
119+
120+
```json
121+
{
122+
"data": {
123+
"id": "1",
124+
"type": "users",
125+
"attributes": {
126+
"name": "Example User"
127+
},
128+
"relationships": {
129+
"microposts": {
130+
"data": [],
131+
"links": {
132+
"related": "/api/v1/microposts?user_id=1"
133+
}
134+
}
135+
}
136+
}
137+
}
138+
```

0 commit comments

Comments
 (0)