Class: TheHelp::Service
- Inherits:
-
Object
- Object
- TheHelp::Service
- Includes:
- ProvidesCallbacks, ServiceCaller
- Defined in:
- lib/the_help/service.rb
Overview
An Abstract Service Class with Authorization and Logging
Define subclasses of Service to build out the service layer of your application.
class CreateNewUserAccount < TheHelp::Service
input :user
input :send_welcome_message, default: true
do
= false
call_service(Authorize, permission: :admin_users,
allowed: ->() { = true })
end
main do
# do something to create the user account
if
call_service(SendWelcomeMessage, user: user,
success: callback(:message_sent))
end
end
callback(:message_sent) do
# do something really important, I'm sure
end
end
class Authorize < TheHelp::Service
input :permission
input :allowed
allow_all: true
main do
if
allowed.call
end
end
end
class SendWelcomeMessage < TheHelp::Service
input :user
input :success, default: ->() { }
main do
# whatever
success.call
end
end
CreateNewUserAccount.(context: current_user, user: new_user_object)
Constant Summary collapse
- CB_NOT_AUTHORIZED =
The default :not_authorized callback
It will raise a TheHelp::NotAuthorizedError when the context is not authorized to perform the service.
->(service:, context:) { raise TheHelp::NotAuthorizedError, "Not authorized to access #{service.name} as #{context.inspect}." }
Class Method Summary collapse
-
.attr_accessor(*names, make_private: false, private_reader: false, private_writer: false) ⇒ Object
Defines attr_accessors with scoping options.
-
.authorization_policy(allow_all: false, &block) ⇒ Object
Defines the service authorization policy.
-
.call(*args) ⇒ Class
Convenience method to instantiate the service and immediately call it.
-
.inherited(other) ⇒ Object
:nodoc:.
- .input(name, **options) ⇒ Object
-
.main(&block) ⇒ Object
Defines the primary routine of the service.
-
.required_inputs ⇒ Object
:nodoc: instances need access to this, otherwise it would be made private.
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(context:, logger: Logger.new($stdout), not_authorized: CB_NOT_AUTHORIZED, **inputs) ⇒ Service
constructor
A new instance of Service.
Methods included from ServiceCaller
Methods included from ProvidesCallbacks
Constructor Details
#initialize(context:, logger: Logger.new($stdout), not_authorized: CB_NOT_AUTHORIZED, **inputs) ⇒ Service
149 150 151 152 153 154 155 |
# File 'lib/the_help/service.rb', line 149 def initialize(context:, logger: Logger.new($stdout), not_authorized: CB_NOT_AUTHORIZED, **inputs) self.context = context self.logger = logger self. = self.inputs = inputs end |
Class Method Details
.attr_accessor(*names, make_private: false, private_reader: false, private_writer: false) ⇒ Object
Defines attr_accessors with scoping options
76 77 78 79 80 81 82 83 |
# File 'lib/the_help/service.rb', line 76 def attr_accessor(*names, make_private: false, private_reader: false, private_writer: false) super(*names) names.each do |name| private name if make_private || private_reader private "#{name}=" if make_private || private_writer end end |
.authorization_policy(allow_all: false, &block) ⇒ Object
Defines the service authorization policy
If allow_all is set to true, or if the provided block (executed in the context of the service object) returns true, then the service will be run when called. Otherwise, the not_authorized callback will be invoked.
125 126 127 128 129 130 131 132 133 |
# File 'lib/the_help/service.rb', line 125 def (allow_all: false, &block) if allow_all define_method(:authorized?) { true } else define_method(:authorized?, &block) end private :authorized? self end |
.call(*args) ⇒ Class
Convenience method to instantiate the service and immediately call it
Any arguments are passed to #initialize
90 91 92 93 |
# File 'lib/the_help/service.rb', line 90 def call(*args) new(*args).call self end |
.inherited(other) ⇒ Object
:nodoc:
96 97 98 |
# File 'lib/the_help/service.rb', line 96 def inherited(other) other.instance_variable_set(:@required_inputs, required_inputs.dup) end |
.input(name, **options) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/the_help/service.rb', line 135 def input(name, **) attr_accessor name, make_private: true if .key?(:default) required_inputs.delete(name) define_method(name) do instance_variable_get("@#{name}") || [:default] end else required_inputs << name end self end |
.main(&block) ⇒ Object
Defines the primary routine of the service
The code that will be run when the service is called, assuming it is unauthorized.
110 111 112 113 114 |
# File 'lib/the_help/service.rb', line 110 def main(&block) define_method(:main, &block) private :main self end |
.required_inputs ⇒ Object
:nodoc: instances need access to this, otherwise it would be made private
102 103 104 |
# File 'lib/the_help/service.rb', line 102 def required_inputs @required_inputs ||= Set.new end |
Instance Method Details
#call ⇒ Object
157 158 159 160 161 162 163 164 165 |
# File 'lib/the_help/service.rb', line 157 def call validate_service_definition catch(:stop) do log_service_call main end self end |