In my Grape API the same model can be accessed by different controllers and endpoints. I need to serialize the same model for each of them, but not every attribute applies to all endpoints. I know there is the "filter" method, but this removes an attribute. I would like to list the valid attributes instead. This seems safer. I figured out the following approach. However, is there a built-in way I'm missing?
Using the code below, I would like to return "id, comments, status, user_id" if called by the "/event_signups" endpoint. I would like to return "id, comments, event_id" if called by the "/user_signups" endpoint.
Serializer
module Mobile
module V4
class SignupSerializer < ActiveModel::Serializer
attributes :id,
:comments,
:status,
:event_id,
:user_id
attribute :id, if: :id?
attribute :comments, if: :comments?
attribute :status, if: :status?
attribute :event_id, if: :event_id?
attribute :user_id, if: :user_id?
def id?
!instance_options[:allowed_attributes].index(:id).nil?
end
def comments?
!instance_options[:allowed_attributes].index(:comments).nil?
end
def status?
!instance_options[:allowed_attributes].index(:status).nil?
end
def event_id?
!instance_options[:allowed_attributes].index(:event_id).nil?
end
def user_id?
!instance_options[:allowed_attributes].index(:user_id).nil?
end
end
end
end
Grape API Endpoints
module Mobile
module V4
class Signups < Mobile::V4::Root
include Mobile::V4::Defaults
resource :signups, desc: 'Operations about the signups' do
desc 'Returns list of user's signups'
oauth2 # This endpoint requires authentication
get '/user_signups', allowed_attributes: [:id, :comments, :event_id] do
Signup.where(user_id: current_user.id)
end
desc 'Returns list of event's signups'
params do
requires :event_id, type: Integer, desc: 'Event ID'
end
oauth2 # This endpoint requires authentication
get '/event_signups', allowed_attributes: [:id, :comments, :status, :user_id] do
Signup.where(event_id: params[:event_id])
end
end
end
end
end
Can you try selecting only the fields you need? Eg