active_model_serializers
active_model_serializers
Ruby on RailsでJSONを整形してくれるライブラリです。
実用性という点では評価してないですが、チョロっと触ったところでは結構便利なので取っ掛かりだけでも。
導入
Gemfileに以下を追加。
gem 'active_model_serializers', '~> 0.10.0'
そして以下。
> bundle install
使い方
active_modelと冠しているだけあってモデル(テーブル)と密接に関係してます。
modelsディレクトリにuser.rbがある場合はserializersディレクトリにuser_serializer.rbを作って、userテーブルのカラムからJSONを加工といった流れですかね。
とはいえテーブルと必ず紐づいている必要はなく完全に独立したserializerも作れます。実際にやってみた方が早いですね。
まず以下のテーブルがあるとします。
Railsでmodelsに以下のように作成されているものとします。
user.rb
class User < ApplicationRecord
has_one :user_attribute
end
user_attribute.rb
class UserAttribute < ApplicationRecord
belongs_to :user
end
active_model_serializers導入後ならserializerコマンドが使えるようになっていますので上記のmodelのserializerを作成します。
> rails g serializer user
> rails g serializer user_attribute
これでserializersというディレクトリと以下のファイルが作成されます。
user_serializer.rb
user_attribute_serializer.rb
必ずしもmodelと同名でなくても構いません。modelと同名の場合は紐づけされ (render使う時に省略型が使えるだけ) ます。
userとuser_attributeは1:1になってます。
showされた場合は以下のようなJSONで返したいとします。
{
"id": 1,
"name": "テスト01",
"attr":{
"user_attribute_id": 1,
"phone": "07011112222",
"memo": "テスト"
}
}
この場合はserializerを以下のように編集します。
user_serializer.rb
class UserSerializer < ActiveModel::Serializer
attributes :id, :name
has_one :user_attribute, key: :attr
end
user_attribute_serializer.rb
class UserAttributeSerializer < ActiveModel::Serializer
attribute :id, key: :user_attribute_id
attributes :phone, :memo
end
各シリアライザにはUserとUserAttributeのオブジェクトが渡されます。
そのフィールドから出力したいものをattributesで指定します。
元のフィールド名を変更したい場合はattributeで key: を指定すれば変更できます。
has_oneのように親子関係を指定できます。こちらも名前を変更したい場合は key: が指定できます。
後はコントローラですが通常なら以下のようにJSONで返すためのハッシュを自前で容易する必要がありました。
@User = User.find(1)
@UserAttr = @User.user_attribute
render json: {
id: @User.id,
name: @User.name,
attr: {
user_attribute_id: @UserAttr.id,
phone: @UserAttr.phone,
memo: @UserAttr.memo
}
}
これがactive_model_serializersが導入されている場合は以下で済みます。
@User = User.find(1)
render json: @User
これで@User (user.rb) に紐づいているuser_serializer.rbが呼び出されで同じ結果のJSONが返されます。
serializerがmodelと同じ名前なら勝手に呼び出されます。
User -> UserSerializer
でも以下のようにすれば別のserializerも呼び出せます。
@User = User.find(1)
render json: @User, serializer: UserXXXXSerializer
上記は単数の場合、複数データを配列で返したい場合は以下です。
@Users = User.all
render json: @Users, each_serializer: UserXXXXSerializer
コードがスッキリしてモデルに対してJSONを紐づけできるので便利です。
ちなみにこちらの方が処理的にも早いらしいです。
項目を追加したいとか加工したいとか
selializerでJSONの項目を追加したり加工したりできます。
例えば現在日時を追加したい場合は :current_datetime を追加。
nameに必ず「様」を付けたい場合は :name_sama を追加。
そして同名のメソッドを追加します。
user_serializer.rb
class UserSerializer < ActiveModel::Serializer
attributes :id, :name
has_one :user_attribute, key: :attr
attributes :current_datetime, :name_sama
def current_datetime
Time.now
end
def name_sama
object.name + "様"
end
end
objectにはrender json: で渡されたものが入ってます。
has_oneなどで別のserializerを使いたい場合
serializerで指定すればOKです。
class UserSerializer < ActiveModel::Serializer
attributes :id, :name
has_one :user_attribute, key: :attr, serializer: :UserAttributeXXXXSerializer
コメント
コメントを投稿