public
Description: Adds the ability to call events that change the state without writing to the database
Homepage: http://acts_as_state_machine_hacks.zilkey.com/
Clone URL: git://github.com/zilkey/acts_as_state_machine_hacks.git
Search Repo:
100644 44 lines (37 sloc) 1.431 kb
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
41
42
43
44
ScottBarron::Acts::StateMachine::SupportingClasses::StateTransition.class_eval do
  def perform(record, db)
    return false unless guard(record)
    loopback = record.current_state == to
    states = record.class.read_inheritable_attribute(:states)
    next_state = states[to]
    old_state = states[record.current_state]
 
    next_state.entering(record) unless loopback
 
    if db
      record.update_attribute(record.class.state_column, to.to_s)
    else
      record.send("#{record.class.state_column}=", to.to_s)
    end
 
    next_state.entered(record) unless loopback
    old_state.exited(record) unless loopback
    true
  end
end
 
ScottBarron::Acts::StateMachine::SupportingClasses::Event.class_eval do
  def fire(record, db = true)
    next_states(record).each do |transition|
      break true if transition.perform(record, db)
    end
  end
end
 
ScottBarron::Acts::StateMachine::ClassMethods.module_eval do
  # the method with the bang updates the database
  # the method without the bang does not
  # this allows for validations to work
  def event(event, opts={}, &block)
    tt = read_inheritable_attribute(:transition_table)
    
    et = read_inheritable_attribute(:event_table)
    e = et[event.to_sym] = ScottBarron::Acts::StateMachine::SupportingClasses::Event.new(event, opts, tt, &block)
 
    define_method("#{event.to_s}!") { e.fire(self) }
    define_method("#{event.to_s}") { e.fire(self, false) }
  end
end