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 203 204 205 206 207 |
# 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 if after.present? ActiveSupport::Deprecation.new.warn("Operations::Command `after:` option is deprecated and will be " \ "removed in 1.0.0. Please use `on_success:` instead") end 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.
256 257 258 |
# File 'lib/operations/command.rb', line 256 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.
220 221 222 |
# File 'lib/operations/command.rb', line 220 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.
225 226 227 228 229 230 |
# File 'lib/operations/command.rb', line 225 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.
251 252 253 |
# File 'lib/operations/command.rb', line 251 def callable(params = EMPTY_HASH, **context) operation_result(unwrap_monad(callable_monad(component(:contract).call(params.to_h, context)))) end |
#form_class ⇒ Object
287 288 289 |
# File 'lib/operations/command.rb', line 287 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.
211 212 213 |
# File 'lib/operations/command.rb', line 211 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.
261 262 263 |
# File 'lib/operations/command.rb', line 261 def possible(params = EMPTY_HASH, **context) operation_result(component(:preconditions).call(params.to_h, context)) end |
#to_hash ⇒ Object
279 280 281 282 283 284 285 |
# File 'lib/operations/command.rb', line 279 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.
236 237 238 239 240 241 |
# File 'lib/operations/command.rb', line 236 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.
275 276 277 |
# File 'lib/operations/command.rb', line 275 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.
245 246 247 |
# File 'lib/operations/command.rb', line 245 def validate(params, **context) operation_result(unwrap_monad(validate_monad(params.to_h, context))) end |