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] #