Module: DataMapper::Is::PersistentStateMachine

Defined in:
lib/dm-is-persistent_state_machine/is/persistent_state_machine.rb

Defined Under Namespace

Modules: ClassMethods, InstanceMethods Classes: DmIsPersistentStateMachineException

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

fired when plugin gets included into Resource



69
70
71
# File 'lib/dm-is-persistent_state_machine/is/persistent_state_machine.rb', line 69

def self.included(base)
  
end

Instance Method Details

#is_persistent_state_machineObject

Methods that should be included in DataMapper::Model. Normally this should just be your generator, so that the namespace does not get cluttered. ClassMethods and InstanceMethods gets added in the specific resources when you fire is :example



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/dm-is-persistent_state_machine/is/persistent_state_machine.rb', line 80

def is_persistent_state_machine
  DataMapper.logger.info "registering persistent state machine..."
  
  # Add class-methods
  extend DataMapper::Is::PersistentStateMachine::ClassMethods
  extend Forwardable
  # Add instance-methods
  include DataMapper::Is::PersistentStateMachine::InstanceMethods
  
  target_model_name = self.name.snake_case
  
  # target object must have a status associated
  property :state_id, Integer, :required => true, :min => 1
  belongs_to :state
  
  has n, Extlib::Inflection.pluralize(target_model_name+"StateChange").snake_case.to_sym, :constraint => :destroy!
  
  # generate a FooState class that is derived from State        
  state_model = Object.full_const_set(self.to_s+"State", Class.new(State))
  # generate a FooStateEvent class that is derived from StateEvent
  event_model = Object.full_const_set(self.to_s+"StateEvent", Class.new(StateEvent))

  state_change_model = Class.new do
    include DataMapper::Resource

    property :id, ::DataMapper::Types::Serial

    property :from_id, Integer,   :required => true, :min => 1
    property :to_id, Integer,     :required => true, :min => 1
    property :user_id, Integer,   :required => true, :min => 1
    property Extlib::Inflection.foreign_key(target_model_name).to_sym, Integer, :required => true, :min => 1
    property :created_at, DateTime

    # associations
    belongs_to :user
    belongs_to :from, "State"
    belongs_to :to,   "State"
    belongs_to target_model_name.to_sym
  end
  
  state_change_model = Object.full_const_set(self.to_s+"StateChange",state_change_model)
  
  self_cached = self
  
  after :save do
    if (@prev_state && @prev_state != state)
      @state_change = state_change_model.create(:from => @prev_state, :to => state, :created_at => DateTime.now, :user => @updating_user, Extlib::Inflection.foreign_key(target_model_name).to_sym => self.id)
      @prev_state = nil # clean up cache
      @user = nil
    end
  end

  # define delegators
  def_delegators :@state, :events        
end