class MovieState < Model
belongs_to :movie
end
class InitialStep
def select
MovieState.where(state: 'initial')
end
def process(movie_state)
movie_state.state = 'in_production'
end
end
class InProductionStep
def select
MovieState.where(state: 'in_production')
end
def process(movie_state)
if movie_state.movie.finished_shooting?
movie_state.state = 'in_theaters'
end
end
end
class MovieWorkflow
def initialize
@steps = []
@steps << InitialStep.new
@steps << InProductionStep.new
end
def run
@steps.each do |step|
step.select.each do |state|
step.process(state)
state.save
end
end
end
end
This makes it very clear when things are happening. It's also easy to debug and test.Of course, there are a lot of limitations, most notably that it can't deal with an async event happening. In my experience though, this can be dealt with by storing the payload of that event somewhere in the db, where the step-selector can access it on next run. One thing this model deals very well with, is delays, which is often part of business processes.
Any thoughts? Does this design have a more formal name?