概要
Ruby 向け JSON:API シリアライザー である Fast JSON API を使用して json を生成する際に、Serializer で定義したキーのうち一部のものだけ指定して使いたいときの話。
前提
以下のような Serializer が定義されているとする。
class PostSerializer
include FastJsonapi::ObjectSerializer
belongs_to :user
attributes :title, :content, :created_at
end
class UserSerializer
include FastJsonapi::ObjectSerializer
atrributes :name, :birth_date
end
手順
上記の Serializer を使って json を生成する処理は以下の通り。
@posts = Post.all
PostSerializer.new(@posts, { include: %i(user) })
このままだと Selializer で定義したキーがすべて使われる。
{
"data": [
{
"id": "1",
"type": "post",
"attributes": {
"title": "post 1",
"content": "hogehogehoge",
"created_at": "2019-12-13T15:00:00.000+09:00"
},
"relationships": {
"user": {
"data": {
"id": "1",
"type": "user"
}
}
},
{
"id": "2",
"type": "post",
"attributes": {
"title": "post 2",
"content": "hogehogehoge",
"created_at": "2019-12-13T15:00:00.000+09:00"
},
"relationships": {
"user": {
"data": {
"id": "2",
"type": "user"
}
}
}
],
"included": [
{
"id": "1",
"type": "user",
"attributes": {
"name": "Alice",
"birth_date": "2019-12-01"
}
},
{
"id": "2",
"type": "user",
"attributes": {
"name": "Bob",
"birth_date": "2019-12-02"
}
}
]
}
ただ、これが色々な箇所から呼び出されるようになると、一部のキーだけ使いたいということが出てくる。
そこで、options
(Serializer.new
の第2引数) に fileds
というキーワードで必要な要素を指定する。
アソシエーション先のモデルを include している場合、そちらも指定する必要がある(下の例で言うと user)ので注意。
@posts = Post.all
options = {
include: %i(user),
fields: {
post: %i(title user)
user: %i(name)
}
}
PostSerializer.new(@posts, options)
上のように fileds
を使ってキーを指定してみると
{
"data": [
{
"id": "1",
"type": "post",
"attributes": {
"title": "post 1"
},
"relationships": {
"user": {
"data": {
"id": "1",
"type": "user"
}
}
},
{
"id": "2",
"type": "post",
"attributes": {
"title": "post 2"
},
"relationships": {
"user": {
"data": {
"id": "2",
"type": "user"
}
}
}
],
"included": [
{
"id": "1",
"type": "user",
"attributes": {
"name": "Alice"
}
},
{
"id": "2",
"type": "user",
"attributes": {
"name": "Bob"
}
}
]
}
といったように出力される要素を制御することができる。
参考