class SmashTheState::Operation
Attributes
state_class[R]
Public Class Methods
call(params = {})
click to toggle source
Runs the operation, creating the state based on the provided params, passing it from step to step and returning the last step.
# File lib/smash_the_state/operation.rb, line 19 def call(params = {}) run_sequence(sequence, params) end
Also aliased as: run
continues_from(prelude)
click to toggle source
inheritance doesn't work with class attr_readers, this method is provided to bootstrap an operation as a continuation of a “prelude” operation
# File lib/smash_the_state/operation.rb, line 26 def continues_from(prelude) @state_class = prelude.state_class && prelude.state_class.dup sequence.steps.concat prelude.sequence.steps # also make the dry run sequence continue dry_run_sequence.steps.concat(prelude.dry_run_sequence.steps) end
custom_validation(&block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 96 def custom_validation(&block) # when we add a validation step, all proceeding steps must not produce # side-effects (subsequent steps are case-by-case) sequence.mark_as_side_effect_free! step :custom_validation do |state, original_state| Operation::State.eval_custom_validator_block(state, original_state, &block) end end
dynamic_schema(&block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 38 def dynamic_schema(&block) sequence.add_step :_dynamic_schema do |params| Operation::State.build(params, &block).new(params) end # make sure that the dynamic schema step that we just added above is always first sequence.steps.unshift sequence.steps.pop end
error(*steps, &block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 60 def error(*steps, &block) steps.each do |step_name| sequence.add_error_handler_for_step(step_name, &block) end end
inherited(child_class)
click to toggle source
# File lib/smash_the_state/operation.rb, line 130 def self.inherited(child_class) # all steps from the parent first need to be cloned new_steps = sequence.steps.map(&:dup) # and then we add them to the child's empty sequence child_class.sequence.steps.concat(new_steps) # also copy the state class over child_class.instance_variable_set(:@state_class, state_class && state_class.dup) # also copy the dry run sequence child_class.dry_run_sequence.steps.concat(dry_run_sequence.steps.map(&:dup)) end
middleware_class(&block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 79 def middleware_class(&block) sequence.middleware_class_block = block end
middleware_step(step_name, options = {})
click to toggle source
# File lib/smash_the_state/operation.rb, line 83 def middleware_step(step_name, options = {}) sequence.add_middleware_step(step_name, options) end
override_step(step_name, options = {}, &block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 51 def override_step(step_name, options = {}, &block) sequence.override_step(step_name, options, &block) # also override the dry run step return if dry_run_sequence.steps_for_name(step_name).length.zero? dry_run_sequence.override_step(step_name, options, &block) end
policy(klass, method_name)
click to toggle source
# File lib/smash_the_state/operation.rb, line 66 def policy(klass, method_name) step :policy do |state, original_state| state.tap do policy_instance = klass.new(original_state.current_user, state) # pass the policy instance back in the NotAuthorized exception so # that the state, the user, and the policy can be inspected policy_instance.send(method_name) || raise(NotAuthorized, policy_instance) end end end
represent(representer)
click to toggle source
# File lib/smash_the_state/operation.rb, line 105 def represent(representer) step :represent, side_effect_free: true do |state| representer.represent(state) end end
schema(&block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 34 def schema(&block) @state_class = Operation::State.build(&block) end
sequence()
click to toggle source
# File lib/smash_the_state/operation.rb, line 111 def sequence @sequence ||= Operation::Sequence.new end
step(step_name, options = {}, &block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 47 def step(step_name, options = {}, &block) sequence.add_step(step_name, options, &block) end
validate(options = {}, &block)
click to toggle source
# File lib/smash_the_state/operation.rb, line 87 def validate(options = {}, &block) # when we add a validation step, all proceeding steps must not produce # side-effects (subsequent steps are case-by-case) sequence.mark_as_side_effect_free! sequence.add_validation_step(options) do |state| Operation::State.extend_validation_directives_block(state, &block) end end
Private Class Methods
error!(state)
click to toggle source
# File lib/smash_the_state/operation.rb, line 117 def error!(state) raise Error, state end
run_sequence(sequence_to_run, params = {})
click to toggle source
# File lib/smash_the_state/operation.rb, line 121 def run_sequence(sequence_to_run, params = {}) # state class can be nil if the schema is never defined. that's ok. in that # situation it's up to the first step to produce the original state and we'll pass # the params themselves in state = state_class && state_class.new(params) sequence_to_run.call(state || params) end