module RailsStateMachine::Callbacks

Public Class Methods

included(model) click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 4
def included(model)
  register_callbacks(model)
  register_validations(model)
end

Private Class Methods

register_callbacks(model) click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 11
def register_callbacks(model)
  model.class_eval do
    before_validation :run_state_events_before_validation
    before_save :register_state_events_for_callbacks
    before_save { flush_state_event_callbacks(:before_save) }
    after_save { flush_state_event_callbacks(:after_save) }
    after_commit { flush_state_event_callbacks(:after_commit) }
  end
end
register_validations(model) click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 21
def register_validations(model)
  model.class_eval do
    after_validation :revert_states, if: -> { errors.any? }
  end
end

Public Instance Methods

flush_state_event_callbacks(name) click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 54
def flush_state_event_callbacks(name)
  if @state_event_callbacks
    while (event = @state_event_callbacks[name].shift)
      event.public_send("run_#{name}", self)
    end
  end
end
register_state_events_for_callbacks() click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 36
def register_state_events_for_callbacks
  @state_event_callbacks ||= {
    before_save: [],
    after_save: [],
    after_commit: []
  }
  state_machine_state_managers.each do |state_manager|
    if (next_event = state_manager.next_event)
      @state_event_callbacks[:before_save] << next_event
      @state_event_callbacks[:after_save] << next_event
      @state_event_callbacks[:after_commit] << next_event
      state_manager.next_event = nil
    end
  end

  true
end
revert_states() click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 62
def revert_states
  state_machine_state_managers.each do |state_manager|
    state_manager.revert
  end
end
run_state_events_before_validation() click to toggle source
# File lib/rails_state_machine/callbacks.rb, line 28
def run_state_events_before_validation
  # Since validations may be skipped, we will not register validation callbacks in @state_event_callbacks,
  # but call them explicitly when before_validation callbacks are triggered.
  state_machine_state_managers.each do |state_manager|
    state_manager.next_event&.run_before_validation(self)
  end
end