Class: Operations::Command
- Inherits:
-
Object
- Object
- Operations::Command
- Extended by:
- Dry::Initializer
- Includes:
- Dry::Core::Constants
- Defined in:
- lib/operations/command.rb
Overview
should they ever happen.
Defined Under Namespace
Classes: OperationFailed
Constant Summary collapse
- COMPONENTS =
%i[contract policies idempotency preconditions operation on_success on_failure].freeze
- FORM_HYDRATOR =
->(_form_class, params, **_context) { params }
Class Method Summary collapse
-
.build(operation, contract = nil, **deps) ⇒ Object
A short-cut to initialize operation by convention:.
Instance Method Summary collapse
-
#allowed(params = EMPTY_HASH, **context) ⇒ Object
Works the same way as ‘callable` but checks only the policy.
-
#call(params, **context) ⇒ Object
Executes all the components in a particular order.
-
#call!(params, **context) ⇒ Object
Works the same way as ‘call` but raises an exception on operation failure.
-
#callable(params = EMPTY_HASH, **context) ⇒ Object
Checks if the operation is possible to call in the current context.
- #form_class ⇒ Object
-
#initialize(operation, policy: Undefined, policies: [Undefined], precondition: nil, preconditions: [], after: [], **options) ⇒ Command
constructor
A new instance of Command.
-
#merge(**changes) ⇒ Object
Instantiates a new command with the given fields updated.
-
#possible(params = EMPTY_HASH, **context) ⇒ Object
Works the same way as ‘callable` but checks only preconditions.
- #to_hash ⇒ Object
-
#try_call!(params, **context) ⇒ Object
Calls the operation and raises an exception in case of a failure but only if preconditions and policies have passed.
-
#valid?(*args, **kwargs) ⇒ Boolean
Returns boolean result instead of Operations::Result for validate method.
-
#validate(params, **context) ⇒ Object
Checks if the operation is valid to call in the current context and parameters.
Constructor Details
#initialize(operation, policy: Undefined, policies: [Undefined], precondition: nil, preconditions: [], after: [], **options) ⇒ Command
Returns a new instance of Command.
192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/operations/command.rb', line 192 def initialize( operation, policy: Undefined, policies: [Undefined], precondition: nil, preconditions: [], after: [], ** ) policies_sum = Array.wrap(policy) + policies result_policies = policies_sum - [Undefined] unless policies_sum == [Undefined, Undefined] [:policies] = result_policies if result_policies preconditions.push(precondition) if precondition.present? super(operation, preconditions: preconditions, on_success: after, **) end |
Class Method Details
.build(operation, contract = nil, **deps) ⇒ Object
A short-cut to initialize operation by convention:
Namespace::OperationName - operation Namespace::OperationName::Contract - contract Namespace::OperationName::Policies - policies Namespace::OperationName::Preconditions - preconditions
All the dependencies are passed to every component’s initializer, so they’d be better tolerant to unknown dependencies. Luckily it is easily achievable with Dry::Initializer. This plays really well with Operations::Convenience
182 183 184 185 186 187 188 189 190 |
# File 'lib/operations/command.rb', line 182 def self.build(operation, contract = nil, **deps) = { contract: (contract || operation::Contract).new(**deps), policies: [operation::Policy.new(**deps)] } [:preconditions] = [operation::Precondition.new(**deps)] if operation.const_defined?(:Precondition) new(operation.new(**deps), **) end |
Instance Method Details
#allowed(params = EMPTY_HASH, **context) ⇒ Object
Works the same way as ‘callable` but checks only the policy.
251 252 253 |
# File 'lib/operations/command.rb', line 251 def allowed(params = EMPTY_HASH, **context) operation_result(component(:policies).call(params.to_h, context)) end |
#call(params, **context) ⇒ Object
Executes all the components in a particular order. Returns the result on any step failure. First it validates the user input with the contract then it checks the policy and preconditions and if everything passes - executes the operation routine. The whole process always happens inside of a DB transaction.
215 216 217 |
# File 'lib/operations/command.rb', line 215 def call(params, **context) operation_result(unwrap_monad(call_monad(params.to_h, context))) end |
#call!(params, **context) ⇒ Object
Works the same way as ‘call` but raises an exception on operation failure.
220 221 222 223 224 225 |
# File 'lib/operations/command.rb', line 220 def call!(params, **context) result = call(params, **context) raise OperationFailed.new(result) if result.failure? result end |
#callable(params = EMPTY_HASH, **context) ⇒ Object
Checks if the operation is possible to call in the current context. Performs both: policy and preconditions checks.
246 247 248 |
# File 'lib/operations/command.rb', line 246 def callable(params = EMPTY_HASH, **context) operation_result(unwrap_monad(callable_monad(component(:contract).call(params.to_h, context)))) end |
#form_class ⇒ Object
282 283 284 |
# File 'lib/operations/command.rb', line 282 def form_class @form_class ||= build_form_class end |
#merge(**changes) ⇒ Object
Instantiates a new command with the given fields updated. Useful for defining multiple commands for a single operation body.
206 207 208 |
# File 'lib/operations/command.rb', line 206 def merge(**changes) self.class.new(operation, **self.class.dry_initializer.attributes(self), **changes) end |
#possible(params = EMPTY_HASH, **context) ⇒ Object
Works the same way as ‘callable` but checks only preconditions.
256 257 258 |
# File 'lib/operations/command.rb', line 256 def possible(params = EMPTY_HASH, **context) operation_result(component(:preconditions).call(params.to_h, context)) end |
#to_hash ⇒ Object
274 275 276 277 278 279 280 |
# File 'lib/operations/command.rb', line 274 def to_hash { **main_components_to_hash, **form_components_to_hash, configuration: configuration } end |
#try_call!(params, **context) ⇒ Object
Calls the operation and raises an exception in case of a failure but only if preconditions and policies have passed. This means that the exception will be raised only on contract or the operation body failure.
231 232 233 234 235 236 |
# File 'lib/operations/command.rb', line 231 def try_call!(params, **context) result = call(params, **context) raise OperationFailed.new(result) if result.failure? && !result.failed_precheck? result end |
#valid?(*args, **kwargs) ⇒ Boolean
Returns boolean result instead of Operations::Result for validate method. True on success and false on failure.
270 271 272 |
# File 'lib/operations/command.rb', line 270 def valid?(*args, **kwargs) validate(*args, **kwargs).success? end |
#validate(params, **context) ⇒ Object
Checks if the operation is valid to call in the current context and parameters. Performs policy preconditions and contract checks.
240 241 242 |
# File 'lib/operations/command.rb', line 240 def validate(params, **context) operation_result(unwrap_monad(validate_monad(params.to_h, context))) end |