state_machine 1.0.1 → 1.0.2
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.
- data/.gitignore +11 -0
- data/.travis.yml +16 -0
- data/.yardopts +5 -0
- data/Appraisals +260 -0
- data/CHANGELOG.rdoc +15 -0
- data/Gemfile +3 -0
- data/README.rdoc +156 -29
- data/Rakefile +31 -57
- data/gemfiles/active_model-3.0.0.gemfile +7 -0
- data/gemfiles/active_model-3.0.0.gemfile.lock +32 -0
- data/gemfiles/active_model-3.0.5.gemfile +7 -0
- data/gemfiles/active_model-3.0.5.gemfile.lock +32 -0
- data/gemfiles/active_record-2.0.0.gemfile +8 -0
- data/gemfiles/active_record-2.0.0.gemfile.lock +30 -0
- data/gemfiles/active_record-2.0.5.gemfile +8 -0
- data/gemfiles/active_record-2.0.5.gemfile.lock +30 -0
- data/gemfiles/active_record-2.1.0.gemfile +8 -0
- data/gemfiles/active_record-2.1.0.gemfile.lock +30 -0
- data/gemfiles/active_record-2.1.2.gemfile +8 -0
- data/gemfiles/active_record-2.1.2.gemfile.lock +30 -0
- data/gemfiles/active_record-2.2.3.gemfile +8 -0
- data/gemfiles/active_record-2.2.3.gemfile.lock +30 -0
- data/gemfiles/active_record-2.3.12.gemfile +8 -0
- data/gemfiles/active_record-2.3.12.gemfile.lock +30 -0
- data/gemfiles/active_record-3.0.0.gemfile +8 -0
- data/gemfiles/active_record-3.0.0.gemfile.lock +44 -0
- data/gemfiles/active_record-3.0.5.gemfile +8 -0
- data/gemfiles/active_record-3.0.5.gemfile.lock +43 -0
- data/gemfiles/data_mapper-0.10.2.gemfile +12 -0
- data/gemfiles/data_mapper-0.10.2.gemfile.lock +45 -0
- data/gemfiles/data_mapper-0.9.11.gemfile +12 -0
- data/gemfiles/data_mapper-0.9.11.gemfile.lock +47 -0
- data/gemfiles/data_mapper-0.9.4.gemfile +12 -0
- data/gemfiles/data_mapper-0.9.4.gemfile.lock +61 -0
- data/gemfiles/data_mapper-0.9.7.gemfile +12 -0
- data/gemfiles/data_mapper-0.9.7.gemfile.lock +57 -0
- data/gemfiles/data_mapper-1.0.0.gemfile +12 -0
- data/gemfiles/data_mapper-1.0.0.gemfile.lock +53 -0
- data/gemfiles/data_mapper-1.0.1.gemfile +12 -0
- data/gemfiles/data_mapper-1.0.1.gemfile.lock +53 -0
- data/gemfiles/data_mapper-1.0.2.gemfile +12 -0
- data/gemfiles/data_mapper-1.0.2.gemfile.lock +53 -0
- data/gemfiles/data_mapper-1.1.0.gemfile +12 -0
- data/gemfiles/data_mapper-1.1.0.gemfile.lock +51 -0
- data/gemfiles/default.gemfile +7 -0
- data/gemfiles/default.gemfile.lock +24 -0
- data/gemfiles/mongo_mapper-0.5.5.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.5.5.gemfile.lock +33 -0
- data/gemfiles/mongo_mapper-0.5.8.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.5.8.gemfile.lock +33 -0
- data/gemfiles/mongo_mapper-0.6.0.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.6.0.gemfile.lock +33 -0
- data/gemfiles/mongo_mapper-0.6.10.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.6.10.gemfile.lock +33 -0
- data/gemfiles/mongo_mapper-0.7.0.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.7.0.gemfile.lock +33 -0
- data/gemfiles/mongo_mapper-0.7.5.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.7.5.gemfile.lock +36 -0
- data/gemfiles/mongo_mapper-0.8.0.gemfile +10 -0
- data/gemfiles/mongo_mapper-0.8.0.gemfile.lock +40 -0
- data/gemfiles/mongo_mapper-0.8.3.gemfile +10 -0
- data/gemfiles/mongo_mapper-0.8.3.gemfile.lock +40 -0
- data/gemfiles/mongo_mapper-0.8.4.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.8.4.gemfile.lock +38 -0
- data/gemfiles/mongo_mapper-0.8.6.gemfile +8 -0
- data/gemfiles/mongo_mapper-0.8.6.gemfile.lock +38 -0
- data/gemfiles/mongo_mapper-0.9.0.gemfile +7 -0
- data/gemfiles/mongo_mapper-0.9.0.gemfile.lock +41 -0
- data/gemfiles/mongoid-2.0.0.gemfile +7 -0
- data/gemfiles/mongoid-2.0.0.gemfile.lock +42 -0
- data/gemfiles/mongoid-2.1.4.gemfile +7 -0
- data/gemfiles/mongoid-2.1.4.gemfile.lock +40 -0
- data/gemfiles/sequel-2.11.0.gemfile +8 -0
- data/gemfiles/sequel-2.11.0.gemfile.lock +28 -0
- data/gemfiles/sequel-2.12.0.gemfile +8 -0
- data/gemfiles/sequel-2.12.0.gemfile.lock +28 -0
- data/gemfiles/sequel-2.8.0.gemfile +8 -0
- data/gemfiles/sequel-2.8.0.gemfile.lock +28 -0
- data/gemfiles/sequel-3.0.0.gemfile +8 -0
- data/gemfiles/sequel-3.0.0.gemfile.lock +28 -0
- data/gemfiles/sequel-3.13.0.gemfile +8 -0
- data/gemfiles/sequel-3.13.0.gemfile.lock +28 -0
- data/gemfiles/sequel-3.14.0.gemfile +8 -0
- data/gemfiles/sequel-3.14.0.gemfile.lock +28 -0
- data/gemfiles/sequel-3.23.0.gemfile +8 -0
- data/gemfiles/sequel-3.23.0.gemfile.lock +28 -0
- data/gemfiles/sequel-3.24.0.gemfile +8 -0
- data/gemfiles/sequel-3.24.0.gemfile.lock +28 -0
- data/lib/state_machine/event.rb +13 -90
- data/lib/state_machine/helper_module.rb +17 -0
- data/lib/state_machine/integrations/active_model.rb +35 -0
- data/lib/state_machine/integrations/active_record.rb +41 -2
- data/lib/state_machine/integrations/data_mapper.rb +17 -2
- data/lib/state_machine/integrations/mongo_mapper.rb +34 -7
- data/lib/state_machine/integrations/mongoid.rb +34 -26
- data/lib/state_machine/integrations/mongoid/versions.rb +29 -3
- data/lib/state_machine/integrations/sequel.rb +22 -72
- data/lib/state_machine/integrations/sequel/versions.rb +87 -6
- data/lib/state_machine/machine.rb +279 -19
- data/lib/state_machine/state.rb +2 -2
- data/lib/state_machine/state_context.rb +133 -0
- data/lib/state_machine/version.rb +3 -0
- data/state_machine.gemspec +22 -0
- data/test/test_helper.rb +1 -3
- data/test/unit/branch_test.rb +1 -3
- data/test/unit/event_collection_test.rb +3 -3
- data/test/unit/event_test.rb +1 -3
- data/test/unit/helper_module_test.rb +17 -0
- data/test/unit/integrations/active_model_test.rb +0 -4
- data/test/unit/integrations/active_record_test.rb +50 -9
- data/test/unit/integrations/data_mapper_test.rb +267 -253
- data/test/unit/integrations/mongo_mapper_test.rb +47 -15
- data/test/unit/integrations/mongoid_test.rb +50 -8
- data/test/unit/integrations/sequel_test.rb +10 -6
- data/test/unit/machine_test.rb +206 -25
- data/test/unit/state_context_test.rb +421 -0
- data/test/unit/state_test.rb +20 -3
- metadata +303 -128
- data/lib/state_machine/condition_proxy.rb +0 -94
- data/test/unit/condition_proxy_test.rb +0 -328
|
@@ -137,7 +137,46 @@ module StateMachine
|
|
|
137
137
|
# end
|
|
138
138
|
#
|
|
139
139
|
# If using the +save+ action for the machine, this option will be ignored as
|
|
140
|
-
# the transaction will be created by ActiveRecord within +save+.
|
|
140
|
+
# the transaction will be created by ActiveRecord within +save+. To avoid
|
|
141
|
+
# this, use a different action like so:
|
|
142
|
+
#
|
|
143
|
+
# class Vehicle < ActiveRecord::Base
|
|
144
|
+
# state_machine :initial => :parked, :use_transactions => false, :action => :save_state do
|
|
145
|
+
# ...
|
|
146
|
+
# end
|
|
147
|
+
#
|
|
148
|
+
# alias_method :save_state, :save
|
|
149
|
+
# end
|
|
150
|
+
#
|
|
151
|
+
# == Validations
|
|
152
|
+
#
|
|
153
|
+
# As mentioned in StateMachine::Machine#state, you can define behaviors,
|
|
154
|
+
# like validations, that only execute for certain states. One *important*
|
|
155
|
+
# caveat here is that, due to a constraint in ActiveRecord's validation
|
|
156
|
+
# framework, custom validators will not work as expected when defined to run
|
|
157
|
+
# in multiple states. For example:
|
|
158
|
+
#
|
|
159
|
+
# class Vehicle < ActiveRecord::Base
|
|
160
|
+
# state_machine do
|
|
161
|
+
# ...
|
|
162
|
+
# state :first_gear, :second_gear do
|
|
163
|
+
# validate :speed_is_legal
|
|
164
|
+
# end
|
|
165
|
+
# end
|
|
166
|
+
# end
|
|
167
|
+
#
|
|
168
|
+
# In this case, the <tt>:speed_is_legal</tt> validation will only get run
|
|
169
|
+
# for the <tt>:second_gear</tt> state. To avoid this, you can define your
|
|
170
|
+
# custom validation like so:
|
|
171
|
+
#
|
|
172
|
+
# class Vehicle < ActiveRecord::Base
|
|
173
|
+
# state_machine do
|
|
174
|
+
# ...
|
|
175
|
+
# state :first_gear, :second_gear do
|
|
176
|
+
# validate {|vehicle| vehicle.speed_is_legal}
|
|
177
|
+
# end
|
|
178
|
+
# end
|
|
179
|
+
# end
|
|
141
180
|
#
|
|
142
181
|
# == Validation errors
|
|
143
182
|
#
|
|
@@ -417,7 +456,7 @@ module StateMachine
|
|
|
417
456
|
# breaks both ancestor lookups and defined?(super). Need to special-case
|
|
418
457
|
# the existence of query attribute methods.
|
|
419
458
|
def owner_class_ancestor_has_method?(scope, method)
|
|
420
|
-
scope == :instance && method == "#{
|
|
459
|
+
scope == :instance && method == "#{attribute}?" ? owner_class : super
|
|
421
460
|
end
|
|
422
461
|
end
|
|
423
462
|
end
|
|
@@ -137,7 +137,10 @@ module StateMachine
|
|
|
137
137
|
#
|
|
138
138
|
# To turn on transactions:
|
|
139
139
|
#
|
|
140
|
-
# class Vehicle
|
|
140
|
+
# class Vehicle
|
|
141
|
+
# include DataMapper::Resource
|
|
142
|
+
# ...
|
|
143
|
+
#
|
|
141
144
|
# state_machine :initial => :parked, :use_transactions => true do
|
|
142
145
|
# ...
|
|
143
146
|
# end
|
|
@@ -145,7 +148,18 @@ module StateMachine
|
|
|
145
148
|
#
|
|
146
149
|
# If using the +save+ action for the machine, this option will be ignored as
|
|
147
150
|
# the transaction behavior will depend on the +save+ implementation within
|
|
148
|
-
# DataMapper.
|
|
151
|
+
# DataMapper. To avoid this, use a different action like so:
|
|
152
|
+
#
|
|
153
|
+
# class Vehicle
|
|
154
|
+
# include DataMapper::Resource
|
|
155
|
+
# ...
|
|
156
|
+
#
|
|
157
|
+
# state_machine :initial => :parked, :use_transactions => false, :action => :save_state do
|
|
158
|
+
# ...
|
|
159
|
+
# end
|
|
160
|
+
#
|
|
161
|
+
# alias_method :save_state, :save
|
|
162
|
+
# end
|
|
149
163
|
#
|
|
150
164
|
# == Validation errors
|
|
151
165
|
#
|
|
@@ -294,6 +308,7 @@ module StateMachine
|
|
|
294
308
|
protected
|
|
295
309
|
# Initializes class-level extensions and defaults for this machine
|
|
296
310
|
def after_initialize
|
|
311
|
+
super
|
|
297
312
|
load_observer_extensions
|
|
298
313
|
end
|
|
299
314
|
|
|
@@ -107,6 +107,40 @@ module StateMachine
|
|
|
107
107
|
# end
|
|
108
108
|
# end
|
|
109
109
|
#
|
|
110
|
+
# == Validations
|
|
111
|
+
#
|
|
112
|
+
# As mentioned in StateMachine::Machine#state, you can define behaviors,
|
|
113
|
+
# like validations, that only execute for certain states. One *important*
|
|
114
|
+
# caveat here is that, due to a constraint in MongoMapper's validation
|
|
115
|
+
# framework, custom validators will not work as expected when defined to run
|
|
116
|
+
# in multiple states. For example:
|
|
117
|
+
#
|
|
118
|
+
# class Vehicle
|
|
119
|
+
# include MongoMapper::Document
|
|
120
|
+
#
|
|
121
|
+
# state_machine do
|
|
122
|
+
# ...
|
|
123
|
+
# state :first_gear, :second_gear do
|
|
124
|
+
# validate :speed_is_legal
|
|
125
|
+
# end
|
|
126
|
+
# end
|
|
127
|
+
# end
|
|
128
|
+
#
|
|
129
|
+
# In this case, the <tt>:speed_is_legal</tt> validation will only get run
|
|
130
|
+
# for the <tt>:second_gear</tt> state. To avoid this, you can define your
|
|
131
|
+
# custom validation like so:
|
|
132
|
+
#
|
|
133
|
+
# class Vehicle
|
|
134
|
+
# include MongoMapper::Document
|
|
135
|
+
#
|
|
136
|
+
# state_machine do
|
|
137
|
+
# ...
|
|
138
|
+
# state :first_gear, :second_gear do
|
|
139
|
+
# validate {|vehicle| vehicle.speed_is_legal}
|
|
140
|
+
# end
|
|
141
|
+
# end
|
|
142
|
+
# end
|
|
143
|
+
#
|
|
110
144
|
# == Validation errors
|
|
111
145
|
#
|
|
112
146
|
# If an event fails to successfully fire because there are no matching
|
|
@@ -260,13 +294,6 @@ module StateMachine
|
|
|
260
294
|
def define_scope(name, scope)
|
|
261
295
|
lambda {|model, values| model.query.merge(model.query(scope.call(values)))}
|
|
262
296
|
end
|
|
263
|
-
|
|
264
|
-
# ActiveModel's use of method_missing / respond_to for attribute methods
|
|
265
|
-
# breaks both ancestor lookups and defined?(super). Need to special-case
|
|
266
|
-
# the existence of query attribute methods.
|
|
267
|
-
def owner_class_ancestor_has_method?(scope, method)
|
|
268
|
-
scope == :instance && method == "#{name}?" || super
|
|
269
|
-
end
|
|
270
297
|
end
|
|
271
298
|
end
|
|
272
299
|
end
|
|
@@ -105,6 +105,40 @@ module StateMachine
|
|
|
105
105
|
# end
|
|
106
106
|
# end
|
|
107
107
|
#
|
|
108
|
+
# == Validations
|
|
109
|
+
#
|
|
110
|
+
# As mentioned in StateMachine::Machine#state, you can define behaviors,
|
|
111
|
+
# like validations, that only execute for certain states. One *important*
|
|
112
|
+
# caveat here is that, due to a constraint in Mongoid's validation
|
|
113
|
+
# framework, custom validators will not work as expected when defined to run
|
|
114
|
+
# in multiple states. For example:
|
|
115
|
+
#
|
|
116
|
+
# class Vehicle
|
|
117
|
+
# include Mongoid::Document
|
|
118
|
+
#
|
|
119
|
+
# state_machine do
|
|
120
|
+
# ...
|
|
121
|
+
# state :first_gear, :second_gear do
|
|
122
|
+
# validate :speed_is_legal
|
|
123
|
+
# end
|
|
124
|
+
# end
|
|
125
|
+
# end
|
|
126
|
+
#
|
|
127
|
+
# In this case, the <tt>:speed_is_legal</tt> validation will only get run
|
|
128
|
+
# for the <tt>:second_gear</tt> state. To avoid this, you can define your
|
|
129
|
+
# custom validation like so:
|
|
130
|
+
#
|
|
131
|
+
# class Vehicle
|
|
132
|
+
# include Mongoid::Document
|
|
133
|
+
#
|
|
134
|
+
# state_machine do
|
|
135
|
+
# ...
|
|
136
|
+
# state :first_gear, :second_gear do
|
|
137
|
+
# validate {|vehicle| vehicle.speed_is_legal}
|
|
138
|
+
# end
|
|
139
|
+
# end
|
|
140
|
+
# end
|
|
141
|
+
#
|
|
108
142
|
# == Validation errors
|
|
109
143
|
#
|
|
110
144
|
# If an event fails to successfully fire because there are no matching
|
|
@@ -262,26 +296,7 @@ module StateMachine
|
|
|
262
296
|
super
|
|
263
297
|
end
|
|
264
298
|
|
|
265
|
-
# Forces the change in state to be recognized regardless of whether the
|
|
266
|
-
# state value actually changed
|
|
267
|
-
def write(object, attribute, value, *args)
|
|
268
|
-
result = super
|
|
269
|
-
|
|
270
|
-
if (attribute == :state || attribute == :event && value) && !object.send("#{self.attribute}_changed?")
|
|
271
|
-
current = read(object, :state)
|
|
272
|
-
object.changes[self.attribute.to_s] = [attribute == :event ? current : value, current]
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
result
|
|
276
|
-
end
|
|
277
|
-
|
|
278
299
|
protected
|
|
279
|
-
# Mongoid uses its own implementation of dirty tracking instead of
|
|
280
|
-
# ActiveModel's and doesn't support the #{attribute}_will_change! APIs
|
|
281
|
-
def supports_dirty_tracking?(object)
|
|
282
|
-
false
|
|
283
|
-
end
|
|
284
|
-
|
|
285
300
|
# Only runs validations on the action if using <tt>:save</tt>
|
|
286
301
|
def runs_validations_on_action?
|
|
287
302
|
action == :save
|
|
@@ -345,13 +360,6 @@ module StateMachine
|
|
|
345
360
|
def define_scope(name, scope)
|
|
346
361
|
lambda {|model, values| model.criteria.where(scope.call(values))}
|
|
347
362
|
end
|
|
348
|
-
|
|
349
|
-
# ActiveModel's use of method_missing / respond_to for attribute methods
|
|
350
|
-
# breaks both ancestor lookups and defined?(super). Need to special-case
|
|
351
|
-
# the existence of query attribute methods.
|
|
352
|
-
def owner_class_ancestor_has_method?(scope, method)
|
|
353
|
-
scope == :instance && method == "#{name}?" || super
|
|
354
|
-
end
|
|
355
363
|
end
|
|
356
364
|
end
|
|
357
365
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
module StateMachine
|
|
2
2
|
module Integrations #:nodoc:
|
|
3
3
|
module Mongoid
|
|
4
|
-
# Assumes Mongoid 2.
|
|
5
|
-
version '2.0.x' do
|
|
4
|
+
# Assumes Mongoid 2.2+ uses ActiveModel 3.1+
|
|
5
|
+
version '2.0.x - 2.1.x' do
|
|
6
6
|
def self.active?
|
|
7
|
-
::Mongoid::VERSION >= '2.0.0' && ::Mongoid::VERSION < '2.
|
|
7
|
+
::Mongoid::VERSION >= '2.0.0' && ::Mongoid::VERSION < '2.2.0'
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def define_action_hook
|
|
@@ -13,6 +13,32 @@ module StateMachine
|
|
|
13
13
|
super
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
version '2.0.x' do
|
|
18
|
+
def self.active?
|
|
19
|
+
::Mongoid::VERSION >= '2.0.0' && ::Mongoid::VERSION < '2.1.0'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Forces the change in state to be recognized regardless of whether the
|
|
23
|
+
# state value actually changed
|
|
24
|
+
def write(object, attribute, value, *args)
|
|
25
|
+
result = super
|
|
26
|
+
|
|
27
|
+
if (attribute == :state || attribute == :event && value) && !object.send("#{self.attribute}_changed?")
|
|
28
|
+
current = read(object, :state)
|
|
29
|
+
object.changes[self.attribute.to_s] = [attribute == :event ? current : value, current]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
result
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
# Mongoid uses its own implementation of dirty tracking instead of
|
|
37
|
+
# ActiveModel's and doesn't support the #{attribute}_will_change! APIs
|
|
38
|
+
def supports_dirty_tracking?(object)
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
end
|
|
16
42
|
end
|
|
17
43
|
end
|
|
18
44
|
end
|
|
@@ -135,7 +135,16 @@ module StateMachine
|
|
|
135
135
|
# end
|
|
136
136
|
#
|
|
137
137
|
# If using the +save+ action for the machine, this option will be ignored as
|
|
138
|
-
# the transaction will be created by Sequel within +save+.
|
|
138
|
+
# the transaction will be created by Sequel within +save+. To avoid
|
|
139
|
+
# this, use a different action like so:
|
|
140
|
+
#
|
|
141
|
+
# class Vehicle < Sequel::Model
|
|
142
|
+
# state_machine :initial => :parked, :use_transactions => false, :action => :save_state do
|
|
143
|
+
# ...
|
|
144
|
+
# end
|
|
145
|
+
#
|
|
146
|
+
# alias_method :save_state, :save
|
|
147
|
+
# end
|
|
139
148
|
#
|
|
140
149
|
# == Validation errors
|
|
141
150
|
#
|
|
@@ -276,22 +285,9 @@ module StateMachine
|
|
|
276
285
|
# initial state of the machine *before* any attributes are set on the
|
|
277
286
|
# object
|
|
278
287
|
def define_state_initializer
|
|
279
|
-
# Hooks in to attribute initialization to set the states *prior* to
|
|
280
|
-
# the attributes being set
|
|
281
288
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
super do |*args|
|
|
285
|
-
self.class.state_machines.initialize_states(self, :static => false)
|
|
286
|
-
changed_columns.clear
|
|
287
|
-
yield(*args) if block_given?
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# Initializes static states
|
|
292
|
-
def set(*)
|
|
293
|
-
self.class.state_machines.initialize_states(self, :dynamic => false) if values.empty?
|
|
294
|
-
super
|
|
289
|
+
def initialize_set(*)
|
|
290
|
+
self.class.state_machines.initialize_states(self) { super }
|
|
295
291
|
end
|
|
296
292
|
end_eval
|
|
297
293
|
end
|
|
@@ -305,70 +301,24 @@ module StateMachine
|
|
|
305
301
|
end
|
|
306
302
|
end
|
|
307
303
|
|
|
308
|
-
#
|
|
309
|
-
# a bit more complicated than other integrations since Sequel doesn't
|
|
310
|
-
# provide an easy way to hook around validation calls
|
|
304
|
+
# Defines validation hooks if the machine's action is to save the model
|
|
311
305
|
def define_action_helpers
|
|
312
306
|
super
|
|
313
|
-
|
|
314
|
-
if action == :save
|
|
315
|
-
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
316
|
-
def valid?(*args)
|
|
317
|
-
yielded = false
|
|
318
|
-
result = self.class.state_machines.transitions(self, :save, :after => false).perform do
|
|
319
|
-
yielded = true
|
|
320
|
-
super
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
if yielded || result
|
|
324
|
-
result
|
|
325
|
-
else
|
|
326
|
-
#{handle_validation_failure}
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
end_eval
|
|
330
|
-
end
|
|
307
|
+
define_validation_hook if action == :save
|
|
331
308
|
end
|
|
332
309
|
|
|
333
|
-
#
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
def #{action_hook}(*)
|
|
341
|
-
yielded = false
|
|
342
|
-
result = self.class.state_machines.transitions(self, :save).perform do
|
|
343
|
-
yielded = true
|
|
344
|
-
super
|
|
345
|
-
end
|
|
346
|
-
|
|
347
|
-
if yielded || result
|
|
348
|
-
result
|
|
349
|
-
else
|
|
350
|
-
#{handle_save_failure}
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
end_eval
|
|
354
|
-
else
|
|
355
|
-
super
|
|
356
|
-
end
|
|
310
|
+
# Adds hooks into validation for automatically firing events
|
|
311
|
+
def define_validation_hook
|
|
312
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
313
|
+
def around_validation(*)
|
|
314
|
+
self.class.state_machines.transitions(self, :save, :after => false).perform { super }
|
|
315
|
+
end
|
|
316
|
+
end_eval
|
|
357
317
|
end
|
|
358
318
|
|
|
359
319
|
# Uses internal save hooks if using the :save action
|
|
360
320
|
def action_hook
|
|
361
|
-
action == :save ? :
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
# Handles whether validation errors should be raised
|
|
365
|
-
def handle_validation_failure
|
|
366
|
-
'raise_on_failure?(args.first || {}) ? raise_hook_failure(:validation) : result'
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
# Handles how save failures are raised
|
|
370
|
-
def handle_save_failure
|
|
371
|
-
'raise_hook_failure(:save)'
|
|
321
|
+
action == :save ? :around_save : super
|
|
372
322
|
end
|
|
373
323
|
|
|
374
324
|
# Creates a scope for finding records *with* a particular state or
|
|
@@ -1,17 +1,70 @@
|
|
|
1
1
|
module StateMachine
|
|
2
2
|
module Integrations #:nodoc:
|
|
3
3
|
module Sequel
|
|
4
|
-
version '2.8.x - 3.
|
|
4
|
+
version '2.8.x - 3.23.x' do
|
|
5
5
|
def self.active?
|
|
6
|
-
!defined?(::Sequel::MAJOR) || ::Sequel::MAJOR == 2 || ::Sequel::MAJOR == 3 && ::Sequel::MINOR <=
|
|
6
|
+
!defined?(::Sequel::MAJOR) || ::Sequel::MAJOR == 2 || ::Sequel::MAJOR == 3 && ::Sequel::MINOR <= 23
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def
|
|
10
|
-
|
|
9
|
+
def define_state_initializer
|
|
10
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
11
|
+
def initialize(*)
|
|
12
|
+
super do |*args|
|
|
13
|
+
self.class.state_machines.initialize_states(self, :static => false)
|
|
14
|
+
changed_columns.clear
|
|
15
|
+
yield(*args) if block_given?
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def set(*)
|
|
20
|
+
self.class.state_machines.initialize_states(self, :dynamic => false) if values.empty?
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
end_eval
|
|
11
24
|
end
|
|
12
25
|
|
|
13
|
-
def
|
|
14
|
-
|
|
26
|
+
def define_validation_hook
|
|
27
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
28
|
+
def valid?(*args)
|
|
29
|
+
yielded = false
|
|
30
|
+
result = self.class.state_machines.transitions(self, :save, :after => false).perform do
|
|
31
|
+
yielded = true
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if yielded || result
|
|
36
|
+
result
|
|
37
|
+
else
|
|
38
|
+
#{handle_validation_failure}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end_eval
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def define_action_hook
|
|
45
|
+
if action == :save
|
|
46
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
47
|
+
def #{action_hook}(*)
|
|
48
|
+
yielded = false
|
|
49
|
+
result = self.class.state_machines.transitions(self, :save).perform do
|
|
50
|
+
yielded = true
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if yielded || result
|
|
55
|
+
result
|
|
56
|
+
else
|
|
57
|
+
#{handle_save_failure}
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end_eval
|
|
61
|
+
else
|
|
62
|
+
super
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def action_hook
|
|
67
|
+
action == :save ? :_save : super
|
|
15
68
|
end
|
|
16
69
|
end
|
|
17
70
|
|
|
@@ -31,6 +84,34 @@ module StateMachine
|
|
|
31
84
|
dataset.model_classes[nil]
|
|
32
85
|
end
|
|
33
86
|
end
|
|
87
|
+
|
|
88
|
+
version '2.8.x - 3.13.x' do
|
|
89
|
+
def self.active?
|
|
90
|
+
!defined?(::Sequel::MAJOR) || ::Sequel::MAJOR == 2 || ::Sequel::MAJOR == 3 && ::Sequel::MINOR <= 13
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def handle_validation_failure
|
|
94
|
+
'raise_on_save_failure ? save_failure(:validation) : result'
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def handle_save_failure
|
|
98
|
+
'save_failure(:save)'
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
version '3.14.x - 3.23.x' do
|
|
103
|
+
def self.active?
|
|
104
|
+
defined?(::Sequel::MAJOR) && ::Sequel::MAJOR == 3 && ::Sequel::MINOR >= 14 && ::Sequel::MINOR <= 23
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def handle_validation_failure
|
|
108
|
+
'raise_on_failure?(args.first || {}) ? raise_hook_failure(:validation) : result'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def handle_save_failure
|
|
112
|
+
'raise_hook_failure(:save)'
|
|
113
|
+
end
|
|
114
|
+
end
|
|
34
115
|
end
|
|
35
116
|
end
|
|
36
117
|
end
|