AshWorkflow.Changes.ConditionalTransition (AshWorkflow v0.6.0)

Copy Markdown View Source

An Ash change that evaluates conditional routes at runtime to determine the transition target.

Routes are evaluated in order. The first route whose when expression matches wins. If no route matches, the changeset gets an error.

Conditions are evaluated against the record as it was loaded, with the transition's accepted input applied on top, so a route can branch on a value the same call supplied:

transition :decide do
  accept [:decision]
  route :approved, when: expr(decision == :approve)
  route :rejected, when: expr(decision == :reject)
end

Only the attributes named in accept are applied. An attribute written by one of the action's own changes is not, so a route still sees the state the record was in when the call arrived. That is what lets a transition decide "has anyone approved before this call?" while the same action records the current approver:

transition :approve do
  route :approved, when: expr(not is_nil(first_approver_id))
  route :in_review, when: expr(is_nil(first_approver_id))
end

first_approver_id is set by a change on :approve, not accepted from the caller, so the first approver reads nil and loops back to :in_review.

This differs from AshWorkflow.Changes.ConditionalOnSuccess, which applies every attribute the changeset carries. An automatic step has no caller supplying input, so the only thing its routes could branch on is what its action computed.

Used internally by the AddActions transformer for transitions with conditional routes. Not intended for direct use.