gotoshin

主に学んだ事の自分メモ用です。記事に書くまでも無いような事はhttps://scrapbox.io/study-diary/に書いてます。

Rails Active Model Serializer 便利な使い方メモ

Railsで開発をしているとActive Model Serializerを使いますが、上手く使う事でかなり楽が出来るため、便利な使い方をメモしておきます。 間違っている箇所がありましたらご指摘下さい。

継承する

Serializer同士で継承する事が出来ます。

例えばユーザの情報を返すUserSerializerが存在するとします。

class UserSerializer < ActiveModel::Serializer
  attributes  :id,
              :last_name,
              :first_name,
end

このSerializerを利用して管理者にのみpassword情報を許可したい場合は 以下のようにUserSerializerを継承したAdmin::UserSerializerを作成し pass_wordをattributesに追加します。

class Admin::UserSerializer < UserSerializer
  attributes :pass_word
end

こうすることでAdmin::UserSerializerを経由したデータには

{
:last_name,
:first_name,
:pass_word
}

が全て含まれます。

経由するSerializerを指定する

しかし、普通に

render json: @user

としてしまうとUserSerializerを経由してしまいます。 そこで

render json: @user,  serializer: Admin::UserSerializer

とする事で指定したAdmin::UserSerializerを経由したデータを取得する事が出来ます。

each_serializerとserializerの違い

whereメソッドで取得したデータに上記の方法でSerializer経由のデータを取得しようとしたのですが 上手くいきませんでした。

こちらの記事が参考になりました。

ActiveModelSerializersの備忘録 - 世界一適当な技術ブログ

  • where等を使って複数レコード取得した場合はrender json: @user, each_serializer: Admin::UserSerializer
  • find等を使って単体レコード取得した場合はrender json: @user, serializer: Admin::UserSerializer

と使い分ける事で、上手くSerializer経由のデータを取得する事が出来ました。

render時にSerializerを経由しないようにする

render json: {user: user}とネストさせる事でSerializerの経由を回避する事が出来ました。

render時以外でシリアライズされたデータを取得する

render json: {user: user, status: status}として、userだけシリアライズされたデータが欲しい場面がありました。

serialized_user = ActiveModel::SerializableResource.new(user, serializer: UserSerializer)

とする事でrender時以外でシリアライズされたデータを取得する事が出来ました。

またシリアライズされたデータをHash形式で取得したい場合.serializable_hashメソッドを使用する事で取得する事が出来ました。

serialized_user_hash = ActiveModel::SerializableResource.new(user, serializer: UserSerializer).serializable_hash

Serializer内に引数を渡す

例えばUserSerializer内で所属店舗の情報を使用したい場合

render json: @user, shop: @shop

とする事でSerializer内で@instance_options[:キー名]

@instance_options[:shop]

でデータを取得する事が出来ます。