odiak's blog

Sinatra で ActiveModel::Serializer を使う

rails-api/activemodelserializers を Sinatra で使うメモ。

AMS が ActionController の render を拡張してる部分を参考にした。
(https://github.com/rails-api/active_model_serializers/blob/master/lib/action_controller/serialization.rb)

まず、 json ヘルパーを定義しておく。

helpers do
  def json(object, **options)
    serializer ||= options.delete(:serializer)
    serializer ||= ActiveModel::Serializer.serializer_for(object)
    if options.key?(:each_serializer)
      options[:serializer] = options[:each_serializer]
    end

    target = serializer ? serializer.new(object, options).as_json : object
    content_type(:json)
    Oj.dump(target)
  end
end

使うときは、

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :email
end

class SpecialUserSerializer < UserSerializer
  attributes :phone_number, :address
end


get '/api/users/:id' do
  user = User.find(params[:id])
  json(user)
end

オプションを指定する場合は、

get '/api/users/:id' do
  user = User.find(params[:id])
  json(user, serializer: SpecialUserSerializer)
end