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