module Flow
A callback driven approach to wrap business logic within database transaction.
Callbacks provide an extensible mechanism for hooking into a Flow
.
Accepts input representing the arguments and options which define the initial state.
When `#trigger` is called on a Flow
, `#execute` is called on Operations sequentially in their given order.
Operations are an ordered list of the behaviors which are executed with (and possibly change) the Flow's state.
The Flow
status is a summary of what has occurred during the runtime, used mainly for analysis and program flow.
Flows where no operation should be persisted unless all are successful should use a transaction.
Triggering a Flow
executes all its operations in sequential order (see `Flow::Flux`) iff it has a valid state.
A Flow is a collection of procedurally executed Operations sharing a common State.
Callbacks provide an extensible mechanism for hooking into a Operation
.
Operations take a state as input.
When an exception is raised during execution, but a handler can rescue, it causes a failure instead.
Operations define a `#behavior` that occurs when `#execute` is called.
When `#execute` is unsuccessful, expected problems are failures and unexpected problems are Exceptions.
The Operation
status is used by the Flow
calling it to determine what to do next; continue on or stop and rollback.
Operations which modify several persisted objects together should use a transaction.
An Operation is a service object which is executed with a State.
RSpec matcher for making assertions on the state of a Flow
or Operation
after it has been run.
class ExampleOperation
def behavior state.foo = "some data" state.bar = "some other data" end
end
class ExampleFlow
operations [ ExampleOperation ]
end
RSpec.describe ExampleOperation, type: :operation do
subject { operation.execute } it { is_expected.to have_on_state foo: "some data" } it { is_expected.to have_on_state foo: instance_of(String) } it { is_expected.to have_on_state foo: "some data", bar: "some other data" }
end
RSpec.describe ExampleFlow, type: :operation do
subject { flow.trigger } it { is_expected.to have_on_state foo: "some data" } it { is_expected.to have_on_state foo: instance_of(String) } it { is_expected.to have_on_state foo: "some data", bar: "some other data" }
end
A State is an aggregation of input and derived data.
A StateProxy adapts a State to an Operation through an Operation's `state_*` accessors.
Constants
- VERSION