app/lib/three_scale/api/responder.rb
class ThreeScale::Api::Responder < ActionController::Responder
private
def api_behavior
resource = serializable
resource = representer.prepare(resource) unless resource.frozen?
case
when get?
display(resource, status: :ok) if controller.stale?(serializable.dup)
when post? # create
display resource, status: :created, location: api_location
when put? || patch? # update
display resource, status: :ok
when delete?
head :ok
else
head :no_content
end
end
def api_location
options.fetch(:location) { controller.request.query_parameters.merge(id: resource.id) }
end
def navigation_location
options.fetch(:location) do
params = controller.params.slice(:controller)
params.merge!(controller.request.query_parameters)
params[:id] = resource.id
params[:action] = :show
# Permitting all parameters here but it is not really secure
params.permit! if params.respond_to?(:permit!)
controller.url_for(params)
end
end
def representer
representer = options[:representer] || controller.representer_for(format, serializable, @options)
representer.tap do |representer|
# FIXME: this is really nasty way
options = (Rails.application.config.representer.default_url_options ||= {})
options[:host] = controller.request.host
end
representer
end
def display_errors
controller.render format => resource_errors, :status => error_status
end
def resource_errors
case represent_on_error
when :resource
representer.prepare(resource)
else
super
end
end
def represent_on_error
options[:represent_on_error] || :resource_errors
end
def error_status
case
when delete?
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
:forbidden # should be more like :conflict (409)
else
:unprocessable_entity
end
end
def serializable
@serializable ||= begin
resource = options.fetch(:serialize){ self.resource }
resource = resource.is_a?(ActiveRecord::Relation) ? ordered_relation(resource).to_a : resource
resource
end
end
def ordered_relation(relation)
relation.order_values.empty? ? relation.order(:id) : relation
end
end