Serializerを触ってみる

Rails の Serializer がよくわからないので、使い方など確認してみる。

目次

参考

シリアライザってなんだ?

シリアライザを調べると、関連ワードとして回路の話や XML など、いろいろなものが出てくる。
データをひとつながりの文字列に起こすのがシリアライザということでいいいらしい。
Rails だと render にオブジェクトをそのまま渡したり、jbuilder を使うことで json を作成していたが、そういった方法の 1 つと解釈しました。

準備

以下コマンドで、user モデルの作成他を行います。

1
2
3
bundle exec rails g scaffold user first_name:string last_name:string
bundle exec rails db:create
bundle exec rails db:migrate

一旦ここで適当な user を登録します。
登録したら、localhost:3000/users.json にアクセスすると、以下のものを返します。

localhost:3000/users.jsonの応答(改行を追加済み)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
{
"id": 1,
"first_name": "A",
"last_name": "a",
"created_at": "2020-02-23T16:53:38.968Z",
"updated_at": "2020-02-23T16:53:38.968Z",
"url": "http://localhost:3000/users/1.json"
},
{
"id": 2,
"first_name": "B",
"last_name": "b",
"created_at": "2020-02-23T16:53:47.524Z",
"updated_at": "2020-02-23T16:53:47.524Z",
"url": "http://localhost:3000/users/2.json"
}
]

active_model_serializers の導入

Gemfile 編集

Gemfile に以下を追記します。

1
gem 'active_model_serializers', '~> 0.10.0'

インストール

以下のコマンドを実行します。

1
2
bundle install
bundle exec rails g serializer user

このコマンドで、app/serializers/user_serializer.rbが作成される。

app/serializers/user_serializer.rb
1
2
3
class UserSerializer < ActiveModel::Serializer
attributes :id
end

コントローラを編集

app/controllers/users_controller.rbの index メソッドを編集。

app/controllers/users_controller.rb
1
2
3
4
5
6
7
def index
@users = User.all
respond_to do |format|
format.html
format.json { render json: @users}
end
end

この段階で、localhost:3000/users.json にアクセスすると、以下のものを返します。

localhost:3000/users.jsonの応答
1
[{ "id": 1 }, { "id": 2 }]

返して来るものが、idだけになりました。
この返してくるものは、正しくは json の形式に従っていません。
シリアライザで、処理する記述としては不十分ということでした。
adapter: :jsonを追記して、app/controllers/users_controller.rbの index メソッドを以下のように再度編集します。

app/controllers/users_controller.rb
1
2
3
4
5
6
7
def index
@users = User.all
respond_to do |format|
format.html
format.json { render json: @users,adapter: :json}
end
end

この段階で、localhost:3000/users.json にアクセスすると、以下のものを返します。

localhost:3000/users.jsonの応答
1
{ "users": [{ "id": 1 }, { "id": 2 }] }

json の形式として、正しい形になりました。

返却する要素を変更する

ここまでは、id のみ返していましたが今度は他の要素も返してみます。
app/serializers/user_serializer.rbを編集し、first_nameも返すようにします。

app/serializers/user_serializer.rb
1
2
3
class UserSerializer < ActiveModel::Serializer
attributes :id,:first_name
end

localhost:3000/users.json にアクセスすると、以下のものを返すようになります。

localhost:3000/users.jsonの応答
1
2
3
4
5
6
{
"users": [
{ "id": 1, "first_name": "A" },
{ "id": 2, "first_name": "B" }
]
}

シリアライザに関数を定義する

app/serializers/user_serializer.rbを編集し、name 要素を返却する json に追加します。
name はモデルに定義がありません。
関数で定義します。

app/serializers/user_serializer.rb
1
2
3
4
5
6
7
class UserSerializer < ActiveModel::Serializer
attributes :id,:name

def name
object.first_name+"-"+object.last_name
end
end

localhost:3000/users.json にアクセスすると、以下のものを返すようになります。

1
2
3
4
5
6
{
"users": [
{ "id": 1, "name": "A-a" },
{ "id": 2, "name": "B-b" }
]
}

name 要素に、[first_name文字列]-[last_name文字列]が設定されました。
用意した関数が効果しています。

index 以外でも適用する

app/serializers/user_serializer.rbを以下のように編集します。

app/serializers/user_serializer.rb
1
2
3
def show
render json: @user,adapter: :json
end

localhost:3000/users/1.json にアクセスすると、以下のものを返します。

1
{ "user": { "id": 1, "name": "A-a" } }

id=1の要素のみ、指定したidnameを取得できました。

別のシリアライザを指定する

app/serializers/user_ex_serializer.rbを用意した。

app/serializers/user_serializer.rb
1
2
3
class UserExSerializer < ActiveModel::Serializer
attributes :id,:first_name,:last_name
end

コントローラを以下のように編集します。

1
2
3
def show
render json: @user,adapter: :json,serializer: UserExSerializer
end

localhost:3000/users/1.json にアクセスすると、以下のものを返します。

1
{ "user": { "id": 1, "first_name": "A", "last_name": "a" } }

serializer:でモデルクラスを指定することで、シリアライザを選択できました。


今回は、シリアライザをというかactive_model_serializersの使い方の入口を確認しました。
アソシエーションに関する設定もできるので、次はその点を触っておきたいところです。

ではでは。