Posted at

active_model_serializersが便利

More than 3 years have passed since last update.

RailsでWeb APIを作る時にJSON形式でレスポンスを返すことは多いと思います。

その際、ControllerでrenderにObjectを渡すが、表示するパラメータを制御するときどうやるか?という問題に悩む人は多いのではないでしょうか。

例えばGET /users/:idにアクセスした結果

{

"id": 1,
"username": "m_nakamura145",
"email": "m_nakamura145@example.com",
"created_at": "2015-12-20T00:00:00.000+09:00",
"updated_at": "2015-12-20T00:00:00.000+09:00",
}

というレスポンスが返ってくるAPIを考えます。

created_atupdated_atをレスポンスに含めたくない場合

user = User.find(params[:id])

user.to_json(except: [:created_at,:updated_at])

のように#to_jsonを使って制限するかもしれません。このように簡単な制御ならいいのですが、新しくカラムを追加したら、関連するオブジェクトをレスポンスに含めたい場合など、#to_json では厳しくなってきます。

そういった細かなJSONの制御を行う場合、active_model_serializers が便利です。


使い方

rails generate serializer Model を実行すると

app/serializers/model_serializer.rbファイルが作成されます。


app/serializers/user_serializer.rb

class UserSerializer < ActiveModel::Serializer

attributes :id, :username,:email, :username_size

has_many :posts

def username_size
object.username.size
end
end


attributes にレスポンスで表示したいパラメータを記述します。

関連オブジェクトで同時に表示したいオブジェクトがある場合はhas_manyhas_oneなどが使えます

関数を定義することで、独自のパラメータを追加することもできます。

このように、Serializerクラスに整形処理を委譲することで、Controllerが綺麗になり見通しが良いコードが書けると思います。

なかなかこのJSONの整形処理の方法は自分の中のベストプラクティスが見つかってないですが、active_model_serializersはかなり綺麗に書けると思ったので積極的に使っていきたいgemだと思いました。:innocent: