Class: Signoff::DSL

Inherits:
Object
  • Object
show all
Defined in:
lib/signoff/dsl.rb

Overview

The receiver for the signoff do … end block. Every method here mutates the Signoff::Definition it was built with.

signoff do
  state :draft
  state :manager_review
  state :approved
  state :rejected

  initial_state :draft

  transition :draft,           to: :manager_review
  transition :manager_review,  to: :approved

  reject_to :rejected

  allow_transition :manager_review do |user|
    user.manager?
  end

  after_transition do |record, event|
    WorkflowNotificationJob.perform_later(record.id, event.id)
  end
end

Instance Method Summary collapse

Constructor Details

#initialize(definition) ⇒ DSL

Returns a new instance of DSL.



29
30
31
# File 'lib/signoff/dsl.rb', line 29

def initialize(definition)
  @definition = definition
end

Instance Method Details

#after_transition(&block) ⇒ Object

Run block after the transition’s transaction commits. Receives (record, event). The created event is already persisted, so this is the right place to enqueue jobs or send mail.

Raises:



84
85
86
87
88
# File 'lib/signoff/dsl.rb', line 84

def after_transition(&block)
  raise DefinitionError, "after_transition requires a block" unless block

  @definition.after_callbacks << block
end

#allow_transition(from_state, &block) ⇒ Object

Authorize transitions out of from_state. The block receives the acting user (and optionally the record) and must return a truthy value to allow the transition.

allow_transition :finance_review do |user, record|
  user.finance_team? && record.amount <= user.approval_limit
end

Raises:



67
68
69
70
71
# File 'lib/signoff/dsl.rb', line 67

def allow_transition(from_state, &block)
  raise DefinitionError, "allow_transition requires a block" unless block

  @definition.add_authorization(from_state, block)
end

#before_transition(&block) ⇒ Object

Run block inside the transition’s transaction, before the state column is written. Receives (record, from_state, to_state).

Raises:



75
76
77
78
79
# File 'lib/signoff/dsl.rb', line 75

def before_transition(&block)
  raise DefinitionError, "before_transition requires a block" unless block

  @definition.before_callbacks << block
end

#initial_state(name) ⇒ Object

Explicitly set the starting state. Defaults to the first declared state.



46
47
48
# File 'lib/signoff/dsl.rb', line 46

def initial_state(name)
  @definition.initial_state = name
end

#reject_to(state) ⇒ Object

The state a record moves to when reject! is called.



56
57
58
# File 'lib/signoff/dsl.rb', line 56

def reject_to(state)
  @definition.reject_state = state
end

#state(name, initial: false) ⇒ Object

Declare a state. Pass initial: true to mark it as the starting state (equivalent to a separate initial_state call).



35
36
37
38
# File 'lib/signoff/dsl.rb', line 35

def state(name, initial: false)
  @definition.add_state(name)
  @definition.initial_state = name if initial
end

#states(*names) ⇒ Object

Declare several states at once: states :draft, :review, :approved.



41
42
43
# File 'lib/signoff/dsl.rb', line 41

def states(*names)
  names.flatten.each { |name| state(name) }
end

#transition(from, to:) ⇒ Object

Declare a forward transition. to accepts a single state or an array.



51
52
53
# File 'lib/signoff/dsl.rb', line 51

def transition(from, to:)
  @definition.add_transition(from, to)
end