darthjee/azeroth

View on GitHub
lib/azeroth/request_handler.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
97%
# frozen_string_literal: true

module Azeroth
  # @api private
  #
  # Handle a request on behalf of the controller
  #
  # Request handler sends messages to the controller
  # in order to get the resource and rendering the response
  class RequestHandler
    autoload :Create,  'azeroth/request_handler/create'
    autoload :Destroy, 'azeroth/request_handler/destroy'
    autoload :Edit,    'azeroth/request_handler/edit'
    autoload :Index,   'azeroth/request_handler/index'
    autoload :New,     'azeroth/request_handler/new'
    autoload :Show,    'azeroth/request_handler/show'
    autoload :Update,  'azeroth/request_handler/update'

    # @param controller [ApplicationController]
    # @param model [Azeroth::Model]
    def initialize(controller, model, options)
      @controller = ControllerInterface.new(controller)
      @model = model
      @options = options
    end

    # process the request
    #
    # No action is performd when format is HTML
    #
    # When format is json, the resource is fetched/processed
    # (by the subclass) and returned as json (decorated)
    #
    # @return [String]
    def process
      return unless json?

      controller.add_headers(headers)
      controller.render_json(
        model.decorate(resource),
        status
      )
    end

    private

    attr_reader :controller, :model, :options
    # @method controller
    # @api private
    # @private
    #
    # Controller to receive the message
    #
    # @return [ApplicationController]

    # @method model
    # @api private
    # @private
    #
    # Model interface
    #
    # @return [Azeroth::Model]

    # @method options
    # @api private
    # @private
    #
    # Handling options
    #
    # @return [Azeroth::Options]

    delegate :params, to: :controller
    # @method params
    # @api private
    # @private
    #
    # request parameters
    #
    # @return [ActionController::Parameters]

    # @private
    #
    # Checks if request format is json
    #
    # @return [TrueClass,FalseClass]
    def json?
      params[:format]&.to_s == 'json'
    end

    # @private
    #
    # Resource to be serialized and returned
    #
    # Must be implemented in subclass
    #
    # @return [Object]
    # @raise Not implmented
    def resource
      raise 'must be implemented in subclass'
    end

    # @private
    #
    # Response status
    #
    # For most requests, status is 200 (+:ok+)
    #
    # Must be implemented in subclasses that will handle
    # status differently
    #
    # @return [Symbol]
    def status
      :ok
    end

    # @private
    #
    # Run a block triggering the event
    #
    # @return [Object] Result of given block
    def trigger_event(event, &block)
      options.event_registry.trigger(event, controller, &block)
    end

    # @private
    #
    # Attributes to be used on resource creating
    #
    # @return [Hash]
    def attributes
      @attributes ||= controller.send("#{model.name}_params")
    end

    # @private
    #
    # Collection scope of the resource
    #
    # @return [ActiveRecord::Relation]
    def collection
      @collection = controller.send(model.plural)
    end

    # @private
    # @abstract
    #
    # Headers to be added
    #
    # @return [Hash]
    def headers
      {}
    end
  end
end