Rails
active_model_serializers

Railsのactive_model_serialiserについて学ぶ②_100DaysOfCodeチャレンジ11日目(Day_11:#100DaysOfCode)

はじめに

この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した11日目の記録です。

動作環境

  • ruby 2.4.1
  • Rails 5.0.1

現在学習している内容のリポジトリ

https://github.com/yuta-ushijima/notebook-api-on-rails

本日学んだこと

  • active_model_serialiser(アクティブ・モデル・シリアライザー)における関連付け

前回に引き続き、active_model_serialiserについて深掘りしていきます。

active_model_serialiserの関連づけ

関連付けのコードは、通常のModelファルとまったく同じ書き方でOK。

class ContactSerializer < ActiveModel::Serializer
  attributes :id, :name, :email, :birthdate

  # モデル同士の関連付け
  belongs_to :kind
  has_many :phones
  has_one :address
end

この状態でGETでAPIを叩くと、次のようなレスポンスになります。

{
    "data": [
        {
            "id": "1",
            "type": "contacts",
            "attributes": {
                "name": "中島 光",
                "email": "rhianna_walsh@maggio.net",
                "birthdate": "2016-05-02",
                "birthday": "2016-05-02T00:00:00+09:00"
            },
            "relationships": {
                "kind": {
                    "data": {
                        "id": "1",
                        "type": "kinds"
                    }
                },
                "phones": {
                    "data": [
                        {
                            "id": 1,
                            "number": "080-6512-3933",
                            "contact-id": 1,
                            "created-at": "2018-06-26T14:37:28.719Z",
                            "updated-at": "2018-06-26T14:37:28.748Z"
                        },
                        {
                            "id": 2,
                            "number": "090-5775-8292",
                            "contact-id": 1,
                            "created-at": "2018-06-26T14:37:28.766Z",
                            "updated-at": "2018-06-26T14:37:28.771Z"
                        },
                        {
                            "id": 3,
                            "number": "070-4705-9581",
                            "contact-id": 1,
                            "created-at": "2018-06-26T14:37:28.778Z",
                            "updated-at": "2018-06-26T14:37:28.784Z"
                        }
                    ]
                },
                "address": {
                    "data": {
                        "id": 1,
                        "street": "1236 丸山Ways",
                        "city": "大岩崎村",
                        "contact_id": 1,
                        "created_at": "2018-06-26T14:37:28.074Z",
                        "updated_at": "2018-06-26T14:37:28.074Z"
                    }
                }
            }
        }
     ]
  }

serialiser.rbに関連付けを記述することで、レスポンスの情報がより詳細にわかるようになりました。

現状では、contactモデルとkindモデルだけserialiser.rbを作成している状態です。

ただ、デフォルトだとレスポンスは関連付けられているモデル名と紐づいているidしか表示されません。

attriburesで記載した全てのフィールドの情報を取得したい場合は、controllerで使われているrenderメソッドのオプションにincludeを指定します。

# app/controllers/contacts_controller.rb
# includeメソッドを使ってシンボルでモデル名を指定
<中略>

  # GET /contacts/1
  def show
    render json: @contact, include: [:kind]
  end

<中略>

includeオプションの引数にシンボルでモデル名を渡せば、ちゃんとid以外のレスポンスが返って来るようになりますよ。

# GETでAPIを叩く
{
    "data": {
        "id": "3",
        "type": "contacts",
        "attributes": {
            "name": "池田 陸",
            "email": "ariane@jacobson.org",
            "birthdate": "2016-10-13",
            "birthday": "2016-10-13T00:00:00+09:00"
        },
        "relationships": {
            "kind": {
                "data": {
                    "id": "3",
                    "type": "kinds"
                }
            },
            "phones": {
                "data": [
                    {
                        "id": 8,
                        "number": "070-5363-4468",
                        "contact-id": 3,
                        "created-at": "2018-06-26T14:37:28.844Z",
                        "updated-at": "2018-06-26T14:37:28.849Z"
                    }
                ]
            },
            "address": {
                "data": {
                    "id": 3,
                    "street": "69280 美桜Plain",
                    "city": "河野町",
                    "contact_id": 3,
                    "created_at": "2018-06-26T14:37:28.091Z",
                    "updated_at": "2018-06-26T14:37:28.091Z"
                }
            }
        }
    },
    "included": [
        {
            "id": "3",
            "type": "kinds",
            "attributes": {
                "description": "Goodbye!"
            }
        }
    ]
}

まとめ

Active_Model_Serialiserを使用しているときにJSON出力に関連するモデルの属性を含めるには、includeオプションを使用すればOKということですね。