Skip to content

Instantly share code, notes, and snippets.

@fooqri
Last active April 2, 2017 15:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fooqri/4549146 to your computer and use it in GitHub Desktop.
Save fooqri/4549146 to your computer and use it in GitHub Desktop.
Simple example of a checklist using ruby state_machine gem
require 'rubygems'
require 'state_machine'
class Item
attr_accessor :name, :description
state_machine :item_state, :initial => :available do
after_transition :available=> :completed, :do => :item_completed
event :finish do
transition [:available] => :completed
end
state :completed do
end
end
def initialize(item_name, item_description, parent = nil)
@name = item_name
@description = item_description
@parent_list = parent
super() # NOTE: This *must* be called, otherwise states won't get initialized
end
def item_completed
puts "finished item #{self.name}"
if @parent_list
@parent_list.child_item_completed
end
end
end
class List
attr_accessor :name, :description, :lists, :items
state_machine :list_state, :initial => :available do
after_transition :started=> :completed, :do => :list_completed
event :start do
transition [:available] => :started
end
event :finish do
transition [:started] => :completed
end
state :started do
# take any actions related to moving to started state.
end
state :completed do
# take any actions related to moving to completed state.
end
end
def initialize(list_name, list_description, parent = nil)
@name = list_name
@description = list_description
@lists = []
@items = []
@parent = parent
super() # NOTE: This *must* be called, otherwise states won't get initialized
end
def add_list(name, description)
@lists << List.new(name, description, self)
@lists.last
end
def add_item (name, description)
@items << Item.new(name, description, self)
@items.last
end
# Called by child item when item is completed. Allows check for
# all items completed.
def child_item_completed
# once the first item is completed consider this list started
if self.list_state == "available"
self.fire_events(:start)
end
# if all items are completed move this list to completed state.
if self.items.select{|i| i.item_state != "completed"}.empty?
self.fire_events(:finish)
end
end
def child_list_completed
# if this is a sublist let parent know this list is completed.
# else this is top level list and everything is completed.
if self.items.select{|i| i.item_state != "completed"}.empty?
if self.lists.select{|l| l.list_state != "completed"}.empty?
self.fire_events(:finish)
end
end
end
def list_completed
if @parent
puts "congrats on completing list #{self.name}"
@parent.child_list_completed
else
puts "congrats on completing project #{self.name}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment