tales of failure and woe

My eight year old has been acting twice his age lately. This is not a compliment.

 

automatically calling acts_as_state_machine events on update

I have used acts_as_state_machine in a few client projects and have recently run across a need on a couple of them to allow RESTful updates to change states, easy enough except I want to be able to call the appropriate events and make the proper transitions if they are possible. So I came up with a little bit of code to do just that.

I’m sure there is a more elegant way to do this but I was pressed for time. :-)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

class Something < ActiveRecord::Base
# Validations
  validate :validate_state_change

# State Machine States
  acts_as_state_machine :initial => :new
  state :new
  state :enabled,   :after => :after_enabled
  state :disabled,  :after => :after_disabled

# State Machine Events
  event :enabled do
    transitions :from => :new,      :to => :enabled
    transitions :from => :disabled, :to => :enabled
  end
  
  event :disabled do
    transitions :from => :new,      :to => :disabled
    transitions :from => :enabled,  :to => :disabled
  end

# Instance Methods
  def validate_state_change
    return if new_record?
    old = self.class.find(id)
    old_state = old.state
    new_state = self.state
    self.state = old_state
    if old_state != new_state
      begin
        if self.method("#{new_state}!").call != true
          errors.add(:state, "cannot transition from #{old_state} to #{new_state}")
        end
      rescue NameError
      end
      self.state = new_state
    end
  end
end