Skip to content

Instantly share code, notes, and snippets.

@nickstenning
Created July 24, 2008 22:39
Show Gist options
  • Save nickstenning/2328 to your computer and use it in GitHub Desktop.
Save nickstenning/2328 to your computer and use it in GitHub Desktop.
class Manager < ActiveRecord::Base
belongs_to :demo
serialize :state
serialize :cache
def after_initialize
@observers = []
end
def kind
read_attribute(:kind) or write_attribute(:kind, "example")
end
def before_save
logger.info "BEFORE SAVE: state = #{read_attribute(:state).to_yaml}"
logger.info "BEFORE SAVE: cache = #{read_attribute(:cache).to_yaml}"
logger.info "setting state to #{state.to_yaml}"
write_attribute(:state, state)
logger.info "setting state to #{cache.to_yaml}"
write_attribute(:cache, cache)
end
def after_save
logger.info "AFTER SAVE: state = #{read_attribute(:state).to_yaml}"
logger.info "AFTER SAVE: cache = #{read_attribute(:cache).to_yaml}"
end
def object
@object ||= new_object
end
def state
object.state
end
def cache
object.cache
end
def completed?(command)
case command
when :rollout
object.position == object.tasks.length
when :rollback
object.position == 0
end
end
def rollout
object.rollout!
end
def rollback
object.rollback!
end
def add_observer( obj )
@observers << obj
object.add_observer( obj )
end
def observed_by?( obj )
@observers.include? obj
end
def task_count
object.tasks.length
end
def method_missing(meth, *args)
if object.respond_to?(meth)
object.send(meth, *args)
else
super(meth, *args)
end
end
private
def new_object
require File.join(RAILS_ROOT, 'lib', 'outback', "#{kind}.rb")
@object = Outback.const_get(kind.camelize).create
logger.info "Restoring state:" +
{'state' => read_attribute(:state), 'cache' => read_attribute(:cache)}.to_yaml
@object.restore_state(read_attribute(:state) || {:direction => 1, :position => 0})
@object.cache = (read_attribute(:cache) || {})
@object
end
end
Loading development environment (Rails 2.1.0)
>> m = Manager.new
=> #<Manager id: nil, state: nil, cache: nil, kind: nil, demo_id: nil, created_at: nil, updated_at: nil>
>> m.cache
Restoring state:---
cache:
state:
=> {}
>> m.cache[:name] = "Mike"
=> "Mike"
>> m.save
BEFORE SAVE: state = ---
BEFORE SAVE: cache = ---
setting state to ---
:direction: 1
:position: 0
setting state to ---
:name: Mike
Manager Create (0.000565) INSERT INTO "managers" ("updated_at", "cache", "kind", "demo_id", "state", "created_at") VALUES('2008-07-24 22:37:28', '---
:name: Mike
', 'example', NULL, '---
:direction: 1
:position: 0
', '2008-07-24 22:37:28')
AFTER SAVE: state = ---
:direction: 1
:position: 0
AFTER SAVE: cache = ---
:name: Mike
=> true
>> m
=> #<Manager id: 16, state: {:direction=>1, :position=>0}, cache: {:name=>"Mike"}, kind: "example", demo_id: nil, created_at: "2008-07-24 22:37:28", updated_at: "2008-07-24 22:37:28">
>> m = Manager.find(16)
Manager Load (0.000491) SELECT * FROM "managers" WHERE ("managers"."id" = 16)
=> #<Manager id: 16, state: {:direction=>1, :position=>0}, cache: {:name=>"Mike"}, kind: "example", demo_id: nil, created_at: "2008-07-24 22:37:28", updated_at: "2008-07-24 22:37:28">
>> m.cache
Restoring state:---
cache:
:name: Mike
state:
:direction: 1
:position: 0
=> {:name=>"Mike"}
>> m.cache[:name] = "John"
=> "John"
>> m.save
BEFORE SAVE: state = ---
:direction: 1
:position: 0
BEFORE SAVE: cache = ---
:name: John
setting state to ---
:direction: 1
:position: 0
setting state to ---
:name: John
AFTER SAVE: state = ---
:direction: 1
:position: 0
AFTER SAVE: cache = ---
:name: John
=> true
>> m = Manager.find(16)
Manager Load (0.000880) SELECT * FROM "managers" WHERE ("managers"."id" = 16)
=> #<Manager id: 16, state: {:direction=>1, :position=>0}, cache: {:name=>"Mike"}, kind: "example", demo_id: nil, created_at: "2008-07-24 22:37:28", updated_at: "2008-07-24 22:37:28">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment