aasm 4.0.3 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +10 -11
- data/CHANGELOG.md +28 -1
- data/Gemfile +6 -2
- data/README.md +31 -12
- data/README_FROM_VERSION_3_TO_4.md +1 -1
- data/aasm.gemspec +9 -10
- data/gemfiles/rails_3.2.gemfile +3 -1
- data/gemfiles/rails_4.0.gemfile +2 -5
- data/gemfiles/rails_4.0_bson1.gemfile +14 -0
- data/gemfiles/rails_4.1.gemfile +2 -5
- data/gemfiles/rails_4.1_bson1.gemfile +14 -0
- data/gemfiles/rails_4.2.gemfile +13 -0
- data/gemfiles/rails_4.2_bson1.gemfile +14 -0
- data/lib/aasm/aasm.rb +1 -19
- data/lib/aasm/base.rb +8 -8
- data/lib/aasm/{event.rb → core/event.rb} +13 -5
- data/lib/aasm/{state.rb → core/state.rb} +1 -1
- data/lib/aasm/{transition.rb → core/transition.rb} +1 -3
- data/lib/aasm/instance_base.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +14 -13
- data/lib/aasm/persistence/base.rb +4 -1
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +174 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +5 -7
- data/lib/aasm/persistence/plain_persistence.rb +24 -0
- data/lib/aasm/persistence/sequel_persistence.rb +2 -0
- data/lib/aasm/persistence.rb +19 -11
- data/lib/aasm/state_machine.rb +1 -1
- data/lib/aasm/version.rb +1 -1
- data/lib/aasm.rb +13 -15
- data/spec/database.rb +5 -1
- data/spec/models/callbacks/basic.rb +75 -0
- data/spec/models/callbacks/guard_within_block.rb +66 -0
- data/spec/models/callbacks/private_method.rb +44 -0
- data/spec/models/callbacks/with_args.rb +61 -0
- data/spec/models/callbacks/with_state_args.rb +26 -0
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +10 -0
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +11 -0
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +12 -0
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +1 -1
- data/spec/models/persistence.rb +79 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/unit/callbacks_spec.rb +101 -62
- data/spec/unit/complex_example_spec.rb +9 -9
- data/spec/unit/event_spec.rb +12 -12
- data/spec/unit/inspection_spec.rb +2 -2
- data/spec/unit/memory_leak_spec.rb +12 -12
- data/spec/unit/persistence/active_record_persistence_spec.rb +58 -72
- data/spec/unit/persistence/mongo_mapper_persistance_spec.rb +135 -0
- data/spec/unit/persistence/mongoid_persistance_spec.rb +4 -10
- data/spec/unit/persistence/sequel_persistence_spec.rb +2 -1
- data/spec/unit/state_spec.rb +2 -2
- data/spec/unit/subclassing_spec.rb +1 -1
- data/spec/unit/transition_spec.rb +33 -33
- metadata +32 -40
- data/spec/models/callback_new_dsl.rb +0 -129
- data/spec/models/guard_within_block.rb +0 -64
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AASM
|
|
4
|
+
module Persistence
|
|
5
|
+
module MongoMapperPersistence
|
|
6
|
+
# This method:
|
|
7
|
+
#
|
|
8
|
+
# * extends the model with ClassMethods
|
|
9
|
+
# * includes InstanceMethods
|
|
10
|
+
#
|
|
11
|
+
# Adds
|
|
12
|
+
#
|
|
13
|
+
# before_validation :aasm_ensure_initial_state, :on => :create
|
|
14
|
+
#
|
|
15
|
+
# As a result, it doesn't matter when you define your methods - the following 2 are equivalent
|
|
16
|
+
#
|
|
17
|
+
# class Foo
|
|
18
|
+
# include MongoMapper::Document
|
|
19
|
+
# def aasm_write_state(state)
|
|
20
|
+
# "bar"
|
|
21
|
+
# end
|
|
22
|
+
# include AASM
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# class Foo < ActiveRecord::Base
|
|
26
|
+
# include MongoMapper::Document
|
|
27
|
+
# include AASM
|
|
28
|
+
# def aasm_write_state(state)
|
|
29
|
+
# "bar"
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
#
|
|
33
|
+
def self.included(base)
|
|
34
|
+
base.send(:include, AASM::Persistence::Base)
|
|
35
|
+
base.extend AASM::Persistence::MongoMapperPersistence::ClassMethods
|
|
36
|
+
base.send(:include, AASM::Persistence::MongoMapperPersistence::InstanceMethods)
|
|
37
|
+
|
|
38
|
+
base.before_create :aasm_ensure_initial_state
|
|
39
|
+
|
|
40
|
+
# ensure state is in the list of states
|
|
41
|
+
base.validate :aasm_validate_states
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module ClassMethods
|
|
45
|
+
|
|
46
|
+
def find_in_state(number, state, *args)
|
|
47
|
+
with_state_scope(state).find!(number, *args)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def count_in_state(state, *args)
|
|
51
|
+
with_state_scope(state).count(*args)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def calculate_in_state(state, *args)
|
|
55
|
+
with_state_scope(state).calculate(*args)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
def with_state_scope(state)
|
|
60
|
+
where(aasm.attribute_name.to_sym => state.to_s)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module InstanceMethods
|
|
65
|
+
|
|
66
|
+
# Writes <tt>state</tt> to the state column and persists it to the database
|
|
67
|
+
#
|
|
68
|
+
# foo = Foo.find(1)
|
|
69
|
+
# foo.aasm.current_state # => :opened
|
|
70
|
+
# foo.close!
|
|
71
|
+
# foo.aasm.current_state # => :closed
|
|
72
|
+
# Foo.find(1).aasm.current_state # => :closed
|
|
73
|
+
#
|
|
74
|
+
# NOTE: intended to be called from an event
|
|
75
|
+
def aasm_write_state(state)
|
|
76
|
+
old_value = read_attribute(self.class.aasm.attribute_name)
|
|
77
|
+
aasm_write_attribute state
|
|
78
|
+
|
|
79
|
+
success = if aasm_skipping_validations
|
|
80
|
+
value = aasm_raw_attribute_value state
|
|
81
|
+
self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm.attribute_name => value) == 1
|
|
82
|
+
else
|
|
83
|
+
self.save
|
|
84
|
+
end
|
|
85
|
+
unless success
|
|
86
|
+
write_attribute(self.class.aasm.attribute_name, old_value)
|
|
87
|
+
return false
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
true
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
|
94
|
+
#
|
|
95
|
+
# foo = Foo.find(1)
|
|
96
|
+
# foo.aasm.current_state # => :opened
|
|
97
|
+
# foo.close
|
|
98
|
+
# foo.aasm.current_state # => :closed
|
|
99
|
+
# Foo.find(1).aasm.current_state # => :opened
|
|
100
|
+
# foo.save
|
|
101
|
+
# foo.aasm.current_state # => :closed
|
|
102
|
+
# Foo.find(1).aasm.current_state # => :closed
|
|
103
|
+
#
|
|
104
|
+
# NOTE: intended to be called from an event
|
|
105
|
+
def aasm_write_state_without_persistence(state)
|
|
106
|
+
aasm_write_attribute state
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
def aasm_enum
|
|
111
|
+
case AASM::StateMachine[self.class].config.enum
|
|
112
|
+
when false then nil
|
|
113
|
+
when true then aasm_guess_enum_method
|
|
114
|
+
when nil then aasm_guess_enum_method if aasm_column_looks_like_enum
|
|
115
|
+
else AASM::StateMachine[self.class].config.enum
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def aasm_column_looks_like_enum
|
|
120
|
+
self.class.keys[self.class.aasm.attribute_name.to_s].type == Integer
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def aasm_guess_enum_method
|
|
124
|
+
self.class.aasm.attribute_name.to_s.pluralize.to_sym
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def aasm_skipping_validations
|
|
128
|
+
AASM::StateMachine[self.class].config.skip_validation_on_save
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def aasm_write_attribute(state)
|
|
132
|
+
write_attribute self.class.aasm.attribute_name, aasm_raw_attribute_value(state)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def aasm_raw_attribute_value(state)
|
|
136
|
+
if aasm_enum
|
|
137
|
+
self.class.send(aasm_enum)[state]
|
|
138
|
+
else
|
|
139
|
+
state.to_s
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Ensures that if the aasm_state column is nil and the record is new
|
|
144
|
+
# that the initial state gets populated before validation on create
|
|
145
|
+
#
|
|
146
|
+
# foo = Foo.new
|
|
147
|
+
# foo.aasm_state # => nil
|
|
148
|
+
# foo.valid?
|
|
149
|
+
# foo.aasm_state # => "open" (where :open is the initial state)
|
|
150
|
+
#
|
|
151
|
+
#
|
|
152
|
+
# foo = Foo.find(:first)
|
|
153
|
+
# foo.aasm_state # => 1
|
|
154
|
+
# foo.aasm_state = nil
|
|
155
|
+
# foo.valid?
|
|
156
|
+
# foo.aasm_state # => nil
|
|
157
|
+
#
|
|
158
|
+
def aasm_ensure_initial_state
|
|
159
|
+
return send("#{self.class.aasm.attribute_name}=", aasm.enter_initial_state.to_s) if send(self.class.aasm.attribute_name).blank?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def aasm_validate_states
|
|
163
|
+
send("#{self.class.aasm.attribute_name}=", aasm.enter_initial_state.to_s) if send(self.class.aasm.attribute_name).blank?
|
|
164
|
+
unless AASM::StateMachine[self.class].config.skip_validation_on_save
|
|
165
|
+
if aasm.current_state && !aasm.states.include?(aasm.current_state)
|
|
166
|
+
self.errors.add(AASM::StateMachine[self.class].config.column , "is invalid")
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end # InstanceMethods
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end # Persistence
|
|
174
|
+
end # AASM
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
1
3
|
module AASM
|
|
2
4
|
module Persistence
|
|
3
5
|
module MongoidPersistence
|
|
@@ -33,11 +35,7 @@ module AASM
|
|
|
33
35
|
base.extend AASM::Persistence::MongoidPersistence::ClassMethods
|
|
34
36
|
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
# base.before_validation_on_create :aasm_ensure_initial_state
|
|
38
|
-
base.before_validation :aasm_ensure_initial_state
|
|
39
|
-
# ensure initial aasm state even when validations are skipped
|
|
40
|
-
base.before_create :aasm_ensure_initial_state
|
|
38
|
+
base.after_initialize :aasm_ensure_initial_state
|
|
41
39
|
end
|
|
42
40
|
|
|
43
41
|
module ClassMethods
|
|
@@ -131,5 +129,5 @@ module AASM
|
|
|
131
129
|
end
|
|
132
130
|
end
|
|
133
131
|
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
132
|
+
end # Persistence
|
|
133
|
+
end # AASM
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module AASM
|
|
2
|
+
module Persistence
|
|
3
|
+
module PlainPersistence
|
|
4
|
+
|
|
5
|
+
def aasm_read_state
|
|
6
|
+
# all the following lines behave like @current_state ||= aasm.enter_initial_state
|
|
7
|
+
current = aasm.instance_variable_get("@current_state")
|
|
8
|
+
return current if current
|
|
9
|
+
aasm.instance_variable_set("@current_state", aasm.enter_initial_state)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# may be overwritten by persistence mixins
|
|
13
|
+
def aasm_write_state(new_state)
|
|
14
|
+
true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# may be overwritten by persistence mixins
|
|
18
|
+
def aasm_write_state_without_persistence(new_state)
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/aasm/persistence.rb
CHANGED
|
@@ -7,23 +7,31 @@ module AASM
|
|
|
7
7
|
hierarchy = base.ancestors.map {|klass| klass.to_s}
|
|
8
8
|
|
|
9
9
|
if hierarchy.include?("ActiveRecord::Base")
|
|
10
|
-
|
|
11
|
-
base.send(:include, AASM::Persistence::ActiveRecordPersistence)
|
|
10
|
+
include_persistence base, :active_record
|
|
12
11
|
elsif hierarchy.include?("Mongoid::Document")
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
include_persistence base, :mongoid
|
|
13
|
+
elsif hierarchy.include?("MongoMapper::Document")
|
|
14
|
+
include_persistence base, :mongo_mapper
|
|
15
15
|
elsif hierarchy.include?("Sequel::Model")
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
include_persistence base, :sequel
|
|
17
|
+
else
|
|
18
|
+
include_persistence base, :plain
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
private
|
|
22
23
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
def include_persistence(base, type)
|
|
25
|
+
require File.join(File.dirname(__FILE__), 'persistence', "#{type}_persistence")
|
|
26
|
+
base.send(:include, constantize("AASM::Persistence::#{capitalize(type)}Persistence"))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def capitalize(string_or_symbol)
|
|
30
|
+
string_or_symbol.to_s.split('_').map {|segment| segment[0].upcase + segment[1..-1]}.join('')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def constantize(string)
|
|
34
|
+
instance_eval(string)
|
|
27
35
|
end
|
|
28
36
|
|
|
29
37
|
end # class << self
|
data/lib/aasm/state_machine.rb
CHANGED
data/lib/aasm/version.rb
CHANGED
data/lib/aasm.rb
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
require 'ostruct'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
aasm
|
|
17
|
-
).each { |file| require File.join(File.dirname(__FILE__), 'aasm', file) }
|
|
3
|
+
require 'aasm/version'
|
|
4
|
+
require 'aasm/errors'
|
|
5
|
+
require 'aasm/configuration'
|
|
6
|
+
require 'aasm/base'
|
|
7
|
+
require 'aasm/dsl_helper'
|
|
8
|
+
require 'aasm/instance_base'
|
|
9
|
+
require 'aasm/core/transition'
|
|
10
|
+
require 'aasm/core/event'
|
|
11
|
+
require 'aasm/core/state'
|
|
12
|
+
require 'aasm/localizer'
|
|
13
|
+
require 'aasm/state_machine'
|
|
14
|
+
require 'aasm/persistence'
|
|
15
|
+
require 'aasm/aasm'
|
data/spec/database.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
ActiveRecord::Migration.suppress_messages do
|
|
2
|
-
%w{gates readers writers transients simples
|
|
2
|
+
%w{gates readers writers transients simples no_scopes no_direct_assignments thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums false_states}.each do |table_name|
|
|
3
3
|
ActiveRecord::Migration.create_table table_name, :force => true do |t|
|
|
4
4
|
t.string "aasm_state"
|
|
5
5
|
end
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
ActiveRecord::Migration.create_table "simple_new_dsls", :force => true do |t|
|
|
9
|
+
t.string "status"
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
ActiveRecord::Migration.create_table "validators", :force => true do |t|
|
|
9
13
|
t.string "name"
|
|
10
14
|
t.string "status"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Callbacks
|
|
2
|
+
class Basic
|
|
3
|
+
include AASM
|
|
4
|
+
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
@fail_event_guard = options[:fail_event_guard]
|
|
7
|
+
@fail_transition_guard = options[:fail_transition_guard]
|
|
8
|
+
@log = options[:log]
|
|
9
|
+
reset_data
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def reset_data
|
|
13
|
+
@data = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def data
|
|
17
|
+
@data.join(' ')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
aasm do
|
|
21
|
+
state :open, :initial => true,
|
|
22
|
+
:before_enter => :before_enter_open,
|
|
23
|
+
:enter => :enter_open,
|
|
24
|
+
:after_enter => :after_enter_open,
|
|
25
|
+
:before_exit => :before_exit_open,
|
|
26
|
+
:exit => :exit_open,
|
|
27
|
+
:after_exit => :after_exit_open
|
|
28
|
+
|
|
29
|
+
state :closed,
|
|
30
|
+
:before_enter => :before_enter_closed,
|
|
31
|
+
:enter => :enter_closed,
|
|
32
|
+
:after_enter => :after_enter_closed,
|
|
33
|
+
:before_exit => :before_exit_closed,
|
|
34
|
+
:exit => :exit_closed,
|
|
35
|
+
:after_exit => :after_exit_closed
|
|
36
|
+
|
|
37
|
+
event :close, :before => :before_event, :after => :after_event, :guard => :event_guard do
|
|
38
|
+
transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :after_transition
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
event :open, :before => :before_event, :after => :after_event do
|
|
42
|
+
transitions :to => :open, :from => :closed
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def log(text)
|
|
47
|
+
@data << text
|
|
48
|
+
puts text if @log
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def aasm_write_state(*args); log('aasm_write_state'); true; end
|
|
52
|
+
|
|
53
|
+
def before_enter_open; log('before_enter_open'); end
|
|
54
|
+
def enter_open; log('enter_open'); end
|
|
55
|
+
def before_exit_open; log('before_exit_open'); end
|
|
56
|
+
def after_enter_open; log('after_enter_open'); end
|
|
57
|
+
def exit_open; log('exit_open'); end
|
|
58
|
+
def after_exit_open; log('after_exit_open'); end
|
|
59
|
+
|
|
60
|
+
def before_enter_closed; log('before_enter_closed'); end
|
|
61
|
+
def enter_closed; log('enter_closed'); end
|
|
62
|
+
def before_exit_closed; log('before_exit_closed'); end
|
|
63
|
+
def exit_closed; log('exit_closed'); end
|
|
64
|
+
def after_enter_closed; log('after_enter_closed'); end
|
|
65
|
+
def after_exit_closed; log('after_exit_closed'); end
|
|
66
|
+
|
|
67
|
+
def event_guard; log('event_guard'); !@fail_event_guard; end
|
|
68
|
+
def transition_guard; log('transition_guard'); !@fail_transition_guard; end
|
|
69
|
+
|
|
70
|
+
def after_transition; log('after_transition'); end
|
|
71
|
+
|
|
72
|
+
def before_event; log('before_event'); end
|
|
73
|
+
def after_event; log('after_event'); end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Callbacks
|
|
2
|
+
class GuardWithinBlock
|
|
3
|
+
include AASM
|
|
4
|
+
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
@fail_event_guard = options[:fail_event_guard]
|
|
7
|
+
@fail_transition_guard = options[:fail_transition_guard]
|
|
8
|
+
@log = options[:log]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
aasm do
|
|
12
|
+
state :open, :initial => true,
|
|
13
|
+
:before_enter => :before_enter_open,
|
|
14
|
+
:enter => :enter_open,
|
|
15
|
+
:after_enter => :after_enter_open,
|
|
16
|
+
:before_exit => :before_exit_open,
|
|
17
|
+
:exit => :exit_open,
|
|
18
|
+
:after_exit => :after_exit_open
|
|
19
|
+
|
|
20
|
+
state :closed,
|
|
21
|
+
:before_enter => :before_enter_closed,
|
|
22
|
+
:enter => :enter_closed,
|
|
23
|
+
:after_enter => :after_enter_closed,
|
|
24
|
+
:before_exit => :before_exit_closed,
|
|
25
|
+
:exit => :exit_closed,
|
|
26
|
+
:after_exit => :after_exit_closed
|
|
27
|
+
|
|
28
|
+
event :close, :before => :before, :after => :after, :guard => :event_guard do
|
|
29
|
+
transitions :to => :closed, :from => [:open], :after => :transitioning do
|
|
30
|
+
guard do
|
|
31
|
+
transition_guard
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
event :open, :before => :before, :after => :after do
|
|
37
|
+
transitions :to => :open, :from => :closed
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def log(text)
|
|
42
|
+
puts text if @log
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def before_enter_open; log('before_enter_open'); end
|
|
46
|
+
def enter_open; log('enter_open'); end
|
|
47
|
+
def before_exit_open; log('before_exit_open'); end
|
|
48
|
+
def after_enter_open; log('after_enter_open'); end
|
|
49
|
+
def exit_open; log('exit_open'); end
|
|
50
|
+
def after_exit_open; log('after_exit_open'); end
|
|
51
|
+
|
|
52
|
+
def before_enter_closed; log('before_enter_closed'); end
|
|
53
|
+
def enter_closed; log('enter_closed'); end
|
|
54
|
+
def before_exit_closed; log('before_exit_closed'); end
|
|
55
|
+
def exit_closed; log('exit_closed'); end
|
|
56
|
+
def after_enter_closed; log('after_enter_closed'); end
|
|
57
|
+
def after_exit_closed; log('after_exit_closed'); end
|
|
58
|
+
|
|
59
|
+
def event_guard; log('event_guard'); !@fail_event_guard; end
|
|
60
|
+
def transition_guard; log('transition_guard'); !@fail_transition_guard; end
|
|
61
|
+
def transitioning; log('transitioning'); end
|
|
62
|
+
|
|
63
|
+
def before; log('before'); end
|
|
64
|
+
def after; log('after'); end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Callbacks
|
|
2
|
+
class PrivateMethod
|
|
3
|
+
include AASM
|
|
4
|
+
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
@fail_event_guard = options[:fail_event_guard]
|
|
7
|
+
@fail_transition_guard = options[:fail_transition_guard]
|
|
8
|
+
@log = options[:log]
|
|
9
|
+
reset_data
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def reset_data
|
|
13
|
+
@data = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def data
|
|
17
|
+
@data.join(' ')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
aasm do
|
|
21
|
+
state :open, :initial => true
|
|
22
|
+
state :closed
|
|
23
|
+
|
|
24
|
+
event :close, :after => :after_event do
|
|
25
|
+
transitions :to => :closed, :from => [:open]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
event :open, :after => :after_event do
|
|
29
|
+
transitions :to => :open, :from => :closed
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def log(text)
|
|
34
|
+
@data << text
|
|
35
|
+
puts text if @log
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def aasm_write_state(*args); log('aasm_write_state'); true; end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def after_event; log('after_event'); end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Callbacks
|
|
2
|
+
class WithArgs
|
|
3
|
+
include AASM
|
|
4
|
+
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
@log = options[:log]
|
|
7
|
+
reset_data
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def reset_data
|
|
11
|
+
@data = []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def data
|
|
15
|
+
@data.join(' ')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
aasm do
|
|
19
|
+
state :open, :initial => true,
|
|
20
|
+
:before_enter => :before_enter_open,
|
|
21
|
+
:after_enter => :after_enter_open,
|
|
22
|
+
:before_exit => :before_exit_open,
|
|
23
|
+
:after_exit => :after_exit_open
|
|
24
|
+
|
|
25
|
+
state :closed,
|
|
26
|
+
:before_enter => :before_enter_closed,
|
|
27
|
+
:after_enter => :after_enter_closed,
|
|
28
|
+
:before_exit => :before_exit_closed,
|
|
29
|
+
:after_exit => :after_exit_closed
|
|
30
|
+
|
|
31
|
+
event :close, :before => :before, :after => :after do
|
|
32
|
+
transitions :to => :closed, :from => [:open], :after => :transition_proc
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
event :open, :before => :before, :after => :after do
|
|
36
|
+
transitions :to => :open, :from => :closed
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def log(text)
|
|
41
|
+
@data << text
|
|
42
|
+
puts text if @log
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def aasm_write_state(*args); log('aasm_write_state'); true; end
|
|
46
|
+
|
|
47
|
+
def before_enter_open; log('before_enter_open'); end
|
|
48
|
+
def before_exit_open; log('before_exit_open'); end
|
|
49
|
+
def after_enter_open; log('after_enter_open'); end
|
|
50
|
+
def after_exit_open; log('after_exit_open'); end
|
|
51
|
+
|
|
52
|
+
def before_enter_closed; log('before_enter_closed'); end
|
|
53
|
+
def before_exit_closed; log('before_enter_closed'); end
|
|
54
|
+
def after_enter_closed; log('after_enter_closed'); end
|
|
55
|
+
def after_exit_closed; log('after_exit_closed'); end
|
|
56
|
+
|
|
57
|
+
def before(arg1, *args); log("before(#{arg1.inspect},#{args.map(&:inspect).join(',')})"); end
|
|
58
|
+
def transition_proc(arg1, arg2); log("transition_proc(#{arg1.inspect},#{arg2.inspect})"); end
|
|
59
|
+
def after(*args); log("after(#{args.map(&:inspect).join(',')})"); end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Callbacks
|
|
2
|
+
class WithStateArg
|
|
3
|
+
|
|
4
|
+
include AASM
|
|
5
|
+
|
|
6
|
+
aasm do
|
|
7
|
+
state :open, :inital => true
|
|
8
|
+
state :closed
|
|
9
|
+
state :out_to_lunch
|
|
10
|
+
|
|
11
|
+
event :close, :before => :before_method, :after => :after_method do
|
|
12
|
+
transitions :to => :closed, :from => [:open], :after => :transition_method
|
|
13
|
+
transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def before_method(arg); end
|
|
18
|
+
|
|
19
|
+
def after_method(arg); end
|
|
20
|
+
|
|
21
|
+
def transition_method(arg); end
|
|
22
|
+
|
|
23
|
+
def transition_method2(arg); end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|