🙆‍♀️

【Rails】ActiveModelSerializersの導入

2021/11/18に公開

ActiveModelSerializersとは?

導入方法

  • gemの追加
# json serializers
gem 'active_model_serializers'
  • Modelに紐づくシリアライズファイルの作成
bundle exec rails g serializer xxx(model名)
  • app/serializers/xxx_serializer.rb の様な形式で作成される

実際に導入してみたメモ

  • 今回は以下の様なtableに対して、json整形をしたい
create_table "events", charset: "utf8mb4", force: :cascade do |t|
    t.bigint "user_id", null: false
    t.string "uuid", null: false
    t.text "image_url", null: false
    t.string "title", null: false
    t.text "content", null: false
    t.boolean "is_close", default: false, null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["user_id"], name: "index_events_on_user_id"
    t.index ["uuid"], name: "index_events_on_uuid", unique: true
end
  • buble exec rails g serializer Event
  • 作成されたファイルはこんな感じ
class EventSerializer < ActiveModel::Serializer
  attributes :id
end
  • コントローラー層でレンダリングする
    • EventSerializerを呼んで、renderしたら先程作成したシリアライザファイル通りに整形してjsonを返却してくれる。
render json: event, serializer: EventSerializer

  • attribueを更新すると
class EventSerializer < ActiveModel::Serializer
  attributes :id, :uuid
end
  • 更新された通りにレンダリングしてくれる

配列で複数のデータを返したい場合

render json: events, each_serializer: EventSerializer

jsonのレスポンスにkey値を定義したい場合

render json: events, root: 'events', adapter: :json, each_serializer: EventSerializer

Attributeを共通化したい場合

bundle exec rails g serializer Application
  • id, created_at, updated_atを定義
class ApplicationSerializer < ActiveModel::Serializer
  attributes :id
  attributes :created_at
  attributes :updated_at
end
class EventSerializer < ApplicationSerializer
  attributes :uuid
end
  • eventのシリアライザで継承する
  • ApplicationSerializerで継承したattributeが追加されている

他のテーブルのデータを出力する場合

  • 出力したいjsonのキー名をattributesに追加
    • 同名のメソッドをシリアライザ内のメソッドとして定義する
class EventSerializer < ApplicationSerializer
	# userテーブルの情報
  attributes :user_name
  attributes :uuid

  def user_name
    object.user.user_name
  end
end

最後に

直感的でわかりにやすいライブラリだなと思った。レンダリング速度周りは調査できてないので気が向いたらする。

Discussion