lib/hanami/extensions/action.rb in hanami-2.0.0.beta4 vs lib/hanami/extensions/action.rb in hanami-2.0.0.rc1
- old
+ new
@@ -1,67 +1,119 @@
# frozen_string_literal: true
require "hanami/action"
-require_relative "../slice_configurable"
-require_relative "action/slice_configured_action"
module Hanami
+ # @api private
module Extensions
- # Extended behavior for actions intended for use within an Hanami app.
+ # Integrated behavior for `Hanami::Action` classes within Hanami apps.
#
- # @see Hanami::Action
+ # @see InstanceMethods
+ # @see https://github.com/hanami/controller
#
# @api public
# @since 2.0.0
module Action
+ # @api private
def self.included(action_class)
super
action_class.extend(Hanami::SliceConfigurable)
action_class.extend(ClassMethods)
action_class.prepend(InstanceMethods)
end
+ # Class methods for app-integrated actions.
+ #
+ # @since 2.0.0
module ClassMethods
+ # @api private
def configure_for_slice(slice)
extend SliceConfiguredAction.new(slice)
end
end
+ # Instance methods for app-integrated actions.
+ #
+ # @since 2.0.0
module InstanceMethods
- attr_reader :view, :view_context, :routes
+ # @api private
+ attr_reader :view
- def initialize(view: nil, view_context: nil, routes: nil, **kwargs)
+ # @api private
+ attr_reader :view_context
+
+ # Returns the app or slice's {Hanami::Slice::RoutesHelper RoutesHelper} for use within
+ # action instance methods.
+ #
+ # @return [Hanami::Slice::RoutesHelper]
+ #
+ # @api public
+ # @since 2.0.0
+ attr_reader :routes
+
+ # Returns the app or slice's `Dry::Monitor::Rack::Middleware` for use within
+ # action instance methods.
+ #
+ # @return [Dry::Monitor::Rack::Middleware]
+ #
+ # @api public
+ # @since 2.0.0
+ attr_reader :rack_monitor
+
+ # @overload def initialize(routes: nil, **kwargs)
+ # Returns a new `Hanami::Action` with app components injected as dependencies.
+ #
+ # These dependencies are injected automatically so that a call to `.new` (with no
+ # arguments) returns a fully integrated action.
+ #
+ # @param routes [Hanami::Slice::RoutesHelper]
+ #
+ # @api public
+ # @since 2.0.0
+ def initialize(view: nil, view_context: nil, rack_monitor: nil, routes: nil, **kwargs)
@view = view
@view_context = view_context
@routes = routes
+ @rack_monitor = rack_monitor
super(**kwargs)
end
private
+ # @api private
def build_response(**options)
options = options.merge(view_options: method(:view_options))
super(**options)
end
+ # @api private
def finish(req, res, halted)
res.render(view, **req.params) if !halted && auto_render?(res)
super
end
+ # @api private
+ def _handle_exception(request, _response, exception)
+ rack_monitor&.instrument(:error, exception: exception, env: request.env)
+
+ super
+ end
+
+ # @api private
def view_options(req, res)
{context: view_context&.with(**view_context_options(req, res))}.compact
end
+ # @api private
def view_context_options(req, res)
{request: req, response: res}
end
# Returns true if a view should automatically be rendered onto the response body.
#
- # This may be overridden to enable/disable automatic rendering.
+ # This may be overridden to enable or disable automatic rendering.
#
# @param res [Hanami::Action::Response]
#
# @return [Boolean]
#