class ApiBlocks::Responder

Public Instance Methods

api_behavior() click to toggle source

Override ActionController::Responder#api_behavior in order to provide one that matches our API documentation.

The only difference so far is that on POST we do not render `status: :created` along with a `Location` header.

Moreover, we display the resource on PUT.

# File lib/api_blocks/responder.rb, line 81
def api_behavior
  raise(MissingRenderer, format) unless has_renderer?

  if get? || post? || put?
    display resource
  else
    head :no_content
  end
end
display_errors() click to toggle source

Display is just a shortcut to render a resource's errors with the current format using `problem_details` when format is set to JSON.

Calls superclass method
# File lib/api_blocks/responder.rb, line 42
def display_errors
  return super unless format == :json

  errors, status = resource_errors

  controller.render problem: errors, status: status
end
has_errors?() click to toggle source
Calls superclass method
# File lib/api_blocks/responder.rb, line 63
def has_errors? # rubocop:disable Naming/PredicateName
  return true if @failure

  super
end
json_resource_errors() click to toggle source
# File lib/api_blocks/responder.rb, line 69
def json_resource_errors
  [{ errors: resource.errors }, :unprocessable_entity]
end
resource_errors() click to toggle source

Override resource_errors to handle more error kinds and return a status code.

Calls superclass method
# File lib/api_blocks/responder.rb, line 18
def resource_errors
  case resource
  when Dry::Validation::Result
    [{ errors: resource.errors.to_h }, :unprocessable_entity]
  when ActiveRecord::RecordInvalid
    [{ errors: resource.record.errors }, :unprocessable_entity]
  when ActiveModel::ValidationError
    [{ errors: resource.model.errors }, :unprocessable_entity]
  when String
    [{ detail: resource }, :internal_server_error]
  when ProblemDetails::Document
    [resource.to_h, resource.status]
  when StandardError
    # propagate the error so it can be handled through the standard rails
    # error handlers.
    raise resource
  else
    super
  end
end
to_format() click to toggle source

All other formats follow the procedure below. First we try to render a template, if the template is not available, we verify if the resource responds to :to_format and display it.

In addition, if the resource is a Dry::Monads::Result we unwrap it and assign the failure instead.

Calls superclass method
# File lib/api_blocks/responder.rb, line 57
def to_format
  unwrap_dry_result if resource.is_a?(Dry::Monads::Result)

  super
end

Private Instance Methods

unwrap_dry_result() click to toggle source
# File lib/api_blocks/responder.rb, line 93
def unwrap_dry_result
  # unwrap the result monad so it can be processed by
  # ActionController::Responder
  resource.fmap { |result| @resource = result }.or do |failure|
    @resource = failure
    @failure = true
  end
end