Last active
August 29, 2015 14:13
-
-
Save reggieb/4f4863a3e43ff49317ab to your computer and use it in GitHub Desktop.
Rollback persisted finite machine: An example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WorkRequest < ActiveRecord::Base | |
# Attributes include :state_history (text) and :state (string) | |
serialize :state_history, Array | |
after_find :restore_process | |
after_initialize :restore_process | |
def rollback_state_to_previous | |
previous_state = state_history.pop | |
return unless previous_state | |
process.restore! previous_state.to_sym | |
self.state = previous_state | |
save | |
end | |
def process | |
@process ||= new_process | |
end | |
delegate :request, :submit, to: :process | |
private | |
def new_process | |
new_process = WorkRequestProcess.new | |
new_process.target(self) | |
new_process | |
end | |
def restore_process | |
process.restore!(state.to_sym) if state.present? | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WorkRequestProcess < FiniteMachine::Definition | |
initial :draft | |
alias_target :work_request | |
events { | |
event :request, { | |
:draft => :requested | |
} | |
event :submit, { | |
:requested => :submitted | |
} | |
} | |
callbacks { | |
on_transition do |event| | |
work_request.state = event.to | |
work_request.state_history << event.from | |
work_request.save | |
end | |
} | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A work request starts in the draft state. To move to the next state:
This triggers the request event and the new state is stored in work_request#state, and the previous state is added to state_history
The work request can then be progressed to the next state:
Which changes the stored attributes to:
To roll back:
Which returns the stored attributes to: