lib/the_help/service.rb in the_help-1.1.4 vs lib/the_help/service.rb in the_help-1.2.0

- old
+ new

@@ -8,58 +8,96 @@ # # Define subclasses of Service to build out the service layer of your # application. # # @example - # class CreateNewUserAccount < TheHelp::Service - # input :user - # input :send_welcome_message, default: true + # class CreateNewUserAccount < TheHelp::Service + # input :user + # input :send_welcome_message, default: true # - # authorization_policy do - # authorized = false - # call_service(Authorize, permission: :admin_users, - # allowed: ->() { authorized = true }) - # authorized + # authorization_policy do + # authorized = false + # call_service(Authorize, permission: :admin_users, + # allowed: ->() { authorized = true }) + # authorized + # end + # + # main do + # # do something to create the user account + # if send_welcome_message + # call_service(SendWelcomeMessage, user: user, + # success: callback(:message_sent)) + # end + # end + # + # callback(:message_sent) do + # # do something really important, I'm sure + # end # end # - # main do - # # do something to create the user account - # if send_welcome_message - # call_service(SendWelcomeMessage, user: user, - # success: callback(:message_sent)) + # class Authorize < TheHelp::Service + # input :permission + # input :allowed + # + # authorization_policy allow_all: true + # + # main do + # if user_has_permission? + # allowed.call + # end # end # end # - # callback(:message_sent) do - # # do something really important, I'm sure + # class SendWelcomeMessage < TheHelp::Service + # input :user + # input :success, default: ->() { } + # + # main do + # # whatever + # success.call + # end # end - # end # - # class Authorize < TheHelp::Service - # input :permission - # input :allowed + # CreateNewUserAccount.(context: current_user, user: new_user_object) # - # authorization_policy allow_all: true + # @example Calling services with a block # - # main do - # if user_has_permission? - # allowed.call + # # Calling a service with a block when the service is not designed to + # # receive one will result in an exception being raised + # + # class DoesNotTakeBlock < TheHelp::Service + # authorization_policy allow_all: true + # + # main do + # # whatever # end # end - # end # - # class SendWelcomeMessage < TheHelp::Service - # input :user - # input :success, default: ->() { } + # DoesNotTakeBlock.call { |result| true } # raises TheHelp::NoResultError # - # main do - # # whatever - # success.call + # # However, if the service *is* designed to receive a block (by explicitly + # # assigning to the internal `#result` attribute in the main routine), the + # # result will be yielded to the block if a block is present. + # + # class CanTakeABlock < TheHelp::Service + # authorization_policy allow_all: true + # + # main do + # self.result = :the_service_result + # end # end - # end # - # CreateNewUserAccount.(context: current_user, user: new_user_object) + # service_result = nil + # + # CanTakeABlock.call() # works just fine + # service_result + # #=> nil # but obviously the result is just discarded + # + # CanTakeABlock.call { |result| service_result = result } + # service_result + # #=> :the_service_result + # class Service include ProvidesCallbacks include ServiceCaller # The default :not_authorized callback @@ -85,12 +123,12 @@ # Convenience method to instantiate the service and immediately call it # # Any arguments are passed to #initialize # # @return [Class] Returns the receiver - def call(*args) - new(*args).call + def call(*args, &block) + new(*args, &block).call self end # :nodoc: def inherited(other) @@ -150,25 +188,34 @@ not_authorized: CB_NOT_AUTHORIZED, **inputs) self.context = context self.logger = logger self.not_authorized = not_authorized self.inputs = inputs + if block_given? + self.result_handler = ->(result) { + yield result + } + end end def call validate_service_definition catch(:stop) do authorize log_service_call main + unless result_handler.nil? + result_handler.call(result) + end end self end private - attr_accessor :context, :logger, :not_authorized + attr_accessor :context, :logger, :not_authorized, :result_handler + attr_writer :result attr_reader :inputs alias service_context context alias service_logger logger @@ -206,8 +253,13 @@ throw :stop end def stop! throw :stop + end + + def result + raise TheHelp::NoResultError unless defined?(@result) + @result end end end