5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】render :json に modelメソッドの返り値を追加する方法

Last updated at Posted at 2022-09-25

きっかけ

controllerの返り値をjson形式で返却する時、モデルで定義されているattributesしか返すことができません。そんな時、他のattributesを追加する方法が分からず困ることがあったので、備忘録として残します。

attributeを追加する

render json: に、methodsオプションをつけ、modelで定義したメソッドを呼び出す。

使い方

例えば・・・
以下のようなモデルがあったとする。

create_table "users", force: :cascade do |t|
  t.string "first_name", null: false
  t.string "last_name", null: false
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end

で、以下のようにでActiveRecordで見つけたuserオブジェクトの結果をjson形式で返す場面があったとする。

user = User.find_by(id: 1)
render json: user

# 返り値
{
  data: {
    id: 1
    first_name: "山田",
    last_name: "太郎",
    updated_at: "2022-09-20T23:34:11.502Z",
    created_at: "2022-09-11T06:11:08.726Z"
  }, 
  status: 200,
  config: {・・・},
  ・・・
}

この返却値の中にモデルメソッドの処理結果を追加したい。
例えば、以下のようにモデルで、Userfull_nameを取得するメソッドがあったとする。
これを先程のjsonデータに含めたい。

class User < ApplicationRecord

  def full_name
    first_name + ' ' + last_name
  end
end

以下のようにmethodsオプションを追記することで、full_nameattributeじゃないにもかかわらず、他のattributeと同じようにHashに取り込まれます。

user = User.find_by(id: 1)
render json: user, methods: :full_name

# 返り値
{
  data: {
    id: 1
    first_name: "山田",
    last_name: "太郎",
    updated_at: "2022-09-20T23:34:11.502Z",
    created_at: "2022-09-11T06:11:08.726Z",
    full_name: "山田 太郎"
  }, 
  status: 200,
  config: {・・・},
  ・・・
}

Railsガイドに書かれている通り、ActiveRecordActiveModel::Serializationモジュールを自動でincludeしているので、インスタンスメソッドである、as_jsonmethodsオプションが何もせずとも使えるようです。

そのため、以下のように書いても同様の結果が得られます

user = User.find_by(id: 1)
render json: user.as_json(methods: :full_name)

必要のないattributeを排除する

こちらもドキュメントに書かれている通り、onlyオプションを追加することで必要なattributeを絞ることができます。他にもオプションが用意されているので状況に応じて使い分けることができます。

user = User.find_by(id: 1)
render json: user, only: [:id, :first_name]

# 返り値
{
  data: {
    id: 1,
    first_name: "山田"
  }, 
  status: 200,
  config: {・・・},
  ・・・
}

参考にした記事

Rails における JSON のシリアライズと向き合う 🦜

最後に

ここまでご覧いただきありがとうございます。m(_ _)m
備忘録のつもりで書きましたが、誰かのお役に立てば嬉しく思います。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?