One of the (many!) ruby projects I’ve been working on required a ruby interface to a legacy database which contains existing state information in numeric form. I’ve been using aasm for other Ruby and Ruby on Rails projects, and since the state is well defined, this seemed like a good opportunity to see if aasm would handle legacy data. I’ve already started to use ActiveRecord with it (this isn’t a Ruby on Rails app, but pure Ruby), so I thought I’d have a quick spike to see what would happen.
A quick look at the source for aasm quickly revealed that it only uses strings for state information in the database, so a translation layer was required.
Since the column name containing the state information wasn’t state, I formulated a slightly cunning plan. Tell aasm that the column was called state, and create state and state= methods that would perform the database translation.
class TestStatus < ActiveRecord::Base
aasm_column :state #required to force aasm to call my state method rather than use its own internal column definition
aasm_state \:ok
aasm_state :fail
aasm_event :fail do
transitions :to => :fail, :from=>[:ok]
end
aasm_event \:ok do
transitions :to => \:ok, :from=>[:fail]
end
LEGACY_STATE={
0=>:ok,
1=>:fail
}
LEGACY_STATE_COLUMN='ErrorState'
def state
LEGACY_STATE[read_attribute(LEGACY_STATE_COLUMN)]
end
def state=(value)
write_attribute(LEGACY_STATE_COLUMN,LEGACY_STATE.invert[value])
end