state_machine 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -11
- data/.travis.yml +49 -7
- data/Appraisals +255 -87
- data/CHANGELOG.md +30 -0
- data/README.md +142 -21
- data/Rakefile +1 -11
- data/examples/Gemfile +5 -0
- data/examples/Gemfile.lock +14 -0
- data/examples/auto_shop.rb +2 -0
- data/examples/car.rb +2 -0
- data/examples/doc/AutoShop.html +2856 -0
- data/examples/doc/AutoShop_state.png +0 -0
- data/examples/doc/Car.html +919 -0
- data/examples/doc/Car_state.png +0 -0
- data/examples/doc/TrafficLight.html +2230 -0
- data/examples/doc/TrafficLight_state.png +0 -0
- data/examples/doc/Vehicle.html +7921 -0
- data/examples/doc/Vehicle_state.png +0 -0
- data/examples/doc/_index.html +136 -0
- data/examples/doc/class_list.html +47 -0
- data/examples/doc/css/common.css +1 -0
- data/examples/doc/css/full_list.css +55 -0
- data/examples/doc/css/style.css +322 -0
- data/examples/doc/file_list.html +46 -0
- data/examples/doc/frames.html +13 -0
- data/examples/doc/index.html +136 -0
- data/examples/doc/js/app.js +205 -0
- data/examples/doc/js/full_list.js +173 -0
- data/examples/doc/js/jquery.js +16 -0
- data/examples/doc/method_list.html +734 -0
- data/examples/doc/top-level-namespace.html +105 -0
- data/examples/rails-rest/migration.rb +1 -5
- data/examples/rails-rest/view__form.html.erb +34 -0
- data/examples/rails-rest/view_edit.html.erb +2 -21
- data/examples/rails-rest/view_index.html.erb +6 -4
- data/examples/rails-rest/view_new.html.erb +2 -11
- data/examples/rails-rest/view_show.html.erb +5 -3
- data/examples/traffic_light.rb +2 -0
- data/examples/vehicle.rb +2 -0
- data/gemfiles/active_model-3.0.0.gemfile.lock +9 -6
- data/gemfiles/active_model-3.0.5.gemfile.lock +10 -7
- data/gemfiles/active_model-3.1.1.gemfile.lock +12 -10
- data/gemfiles/{active_model-3.2.0.gemfile → active_model-3.2.1.gemfile} +1 -1
- data/gemfiles/{graphviz-0.9.0.gemfile → active_model-3.2.12.gemfile} +1 -1
- data/gemfiles/active_model-3.2.12.gemfile.lock +36 -0
- data/gemfiles/{active_record-3.2.0.gemfile → active_model-3.2.13.rc1.gemfile} +1 -2
- data/gemfiles/active_model-3.2.13.rc1.gemfile.lock +36 -0
- data/gemfiles/active_model-4.0.0.gemfile +9 -0
- data/gemfiles/active_model-4.0.0.gemfile.lock +78 -0
- data/gemfiles/active_record-2.0.0.gemfile +2 -1
- data/gemfiles/active_record-2.0.0.gemfile.lock +15 -6
- data/gemfiles/active_record-2.0.5.gemfile +2 -1
- data/gemfiles/active_record-2.0.5.gemfile.lock +15 -6
- data/gemfiles/active_record-2.1.0.gemfile +2 -1
- data/gemfiles/active_record-2.1.0.gemfile.lock +15 -6
- data/gemfiles/active_record-2.1.2.gemfile +2 -1
- data/gemfiles/active_record-2.1.2.gemfile.lock +15 -6
- data/gemfiles/active_record-2.2.3.gemfile +2 -1
- data/gemfiles/active_record-2.2.3.gemfile.lock +15 -6
- data/gemfiles/active_record-2.3.12.gemfile +2 -1
- data/gemfiles/active_record-2.3.12.gemfile.lock +15 -6
- data/gemfiles/active_record-2.3.5.gemfile +9 -0
- data/gemfiles/active_record-2.3.5.gemfile.lock +39 -0
- data/gemfiles/active_record-3.0.0.gemfile +2 -1
- data/gemfiles/active_record-3.0.0.gemfile.lock +18 -11
- data/gemfiles/active_record-3.0.5.gemfile +2 -1
- data/gemfiles/active_record-3.0.5.gemfile.lock +19 -12
- data/gemfiles/active_record-3.1.1.gemfile +2 -1
- data/gemfiles/active_record-3.1.1.gemfile.lock +22 -16
- data/gemfiles/active_record-3.2.12.gemfile +9 -0
- data/gemfiles/active_record-3.2.12.gemfile.lock +51 -0
- data/gemfiles/active_record-3.2.13.rc1.gemfile +9 -0
- data/gemfiles/active_record-3.2.13.rc1.gemfile.lock +51 -0
- data/gemfiles/active_record-4.0.0.gemfile +11 -0
- data/gemfiles/active_record-4.0.0.gemfile.lock +83 -0
- data/gemfiles/data_mapper-0.10.2.gemfile +1 -0
- data/gemfiles/data_mapper-0.10.2.gemfile.lock +13 -9
- data/gemfiles/data_mapper-0.9.11.gemfile +1 -0
- data/gemfiles/data_mapper-0.9.11.gemfile.lock +31 -7
- data/gemfiles/data_mapper-0.9.4.gemfile.lock +25 -14
- data/gemfiles/data_mapper-0.9.7.gemfile +1 -0
- data/gemfiles/data_mapper-0.9.7.gemfile.lock +27 -15
- data/gemfiles/data_mapper-1.0.0.gemfile.lock +20 -17
- data/gemfiles/data_mapper-1.0.1.gemfile.lock +20 -17
- data/gemfiles/data_mapper-1.0.2.gemfile.lock +20 -17
- data/gemfiles/data_mapper-1.1.0.gemfile.lock +19 -16
- data/gemfiles/data_mapper-1.2.0.gemfile.lock +19 -16
- data/gemfiles/default.gemfile.lock +8 -5
- data/gemfiles/graphviz-0.9.17.gemfile +7 -0
- data/gemfiles/graphviz-0.9.17.gemfile.lock +29 -0
- data/gemfiles/graphviz-0.9.21.gemfile.lock +7 -4
- data/gemfiles/graphviz-1.0.0.gemfile.lock +7 -4
- data/gemfiles/graphviz-1.0.3.gemfile +7 -0
- data/gemfiles/graphviz-1.0.3.gemfile.lock +29 -0
- data/gemfiles/graphviz-1.0.8.gemfile +7 -0
- data/gemfiles/graphviz-1.0.8.gemfile.lock +29 -0
- data/gemfiles/mongo_mapper-0.10.0.gemfile +1 -0
- data/gemfiles/mongo_mapper-0.10.0.gemfile.lock +14 -11
- data/gemfiles/mongo_mapper-0.11.1.gemfile +7 -0
- data/gemfiles/mongo_mapper-0.11.1.gemfile.lock +44 -0
- data/gemfiles/mongo_mapper-0.11.2.gemfile +9 -0
- data/gemfiles/mongo_mapper-0.11.2.gemfile.lock +48 -0
- data/gemfiles/mongo_mapper-0.12.0.gemfile +9 -0
- data/gemfiles/mongo_mapper-0.12.0.gemfile.lock +48 -0
- data/gemfiles/mongo_mapper-0.5.5.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.5.8.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.6.0.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.6.10.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.7.0.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.7.5.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.0.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.3.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.4.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.6.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.9.0.gemfile.lock +7 -4
- data/gemfiles/mongoid-2.0.0.gemfile +2 -0
- data/gemfiles/mongoid-2.0.0.gemfile.lock +22 -18
- data/gemfiles/mongoid-2.1.4.gemfile +2 -0
- data/gemfiles/mongoid-2.1.4.gemfile.lock +21 -17
- data/gemfiles/mongoid-2.2.4.gemfile +2 -0
- data/gemfiles/mongoid-2.2.4.gemfile.lock +21 -17
- data/gemfiles/mongoid-2.3.3.gemfile +2 -0
- data/gemfiles/mongoid-2.3.3.gemfile.lock +21 -17
- data/gemfiles/mongoid-2.4.0.gemfile +9 -0
- data/gemfiles/mongoid-2.4.0.gemfile.lock +47 -0
- data/gemfiles/mongoid-2.4.10.gemfile +9 -0
- data/gemfiles/mongoid-2.4.10.gemfile.lock +47 -0
- data/gemfiles/mongoid-2.5.2.gemfile +9 -0
- data/gemfiles/mongoid-2.5.2.gemfile.lock +47 -0
- data/gemfiles/mongoid-2.6.0.gemfile +9 -0
- data/gemfiles/mongoid-2.6.0.gemfile.lock +47 -0
- data/gemfiles/mongoid-3.0.0.gemfile +8 -0
- data/gemfiles/mongoid-3.0.0.gemfile.lock +45 -0
- data/gemfiles/mongoid-3.0.22.gemfile +8 -0
- data/gemfiles/mongoid-3.0.22.gemfile.lock +45 -0
- data/gemfiles/mongoid-3.1.0.gemfile +8 -0
- data/gemfiles/mongoid-3.1.0.gemfile.lock +45 -0
- data/gemfiles/sequel-2.11.0.gemfile +2 -1
- data/gemfiles/sequel-2.11.0.gemfile.lock +11 -6
- data/gemfiles/sequel-2.12.0.gemfile +2 -1
- data/gemfiles/sequel-2.12.0.gemfile.lock +11 -6
- data/gemfiles/sequel-2.8.0.gemfile +2 -1
- data/gemfiles/sequel-2.8.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.0.0.gemfile +2 -1
- data/gemfiles/sequel-3.0.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.10.0.gemfile +9 -0
- data/gemfiles/sequel-3.10.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.13.0.gemfile +2 -1
- data/gemfiles/sequel-3.13.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.14.0.gemfile +2 -1
- data/gemfiles/sequel-3.14.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.23.0.gemfile +2 -1
- data/gemfiles/sequel-3.23.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.24.0.gemfile +2 -1
- data/gemfiles/sequel-3.24.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.29.0.gemfile +2 -1
- data/gemfiles/sequel-3.29.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.34.0.gemfile +9 -0
- data/gemfiles/sequel-3.34.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.35.0.gemfile +9 -0
- data/gemfiles/sequel-3.35.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.4.0.gemfile +9 -0
- data/gemfiles/sequel-3.4.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.44.0.gemfile +9 -0
- data/gemfiles/sequel-3.44.0.gemfile.lock +33 -0
- data/lib/state_machine.rb +6 -0
- data/lib/state_machine/branch.rb +9 -8
- data/lib/state_machine/callback.rb +2 -2
- data/lib/state_machine/core.rb +10 -0
- data/lib/state_machine/core_ext.rb +1 -0
- data/lib/state_machine/eval_helpers.rb +5 -3
- data/lib/state_machine/event.rb +17 -6
- data/lib/state_machine/graph.rb +92 -0
- data/lib/state_machine/integrations.rb +13 -1
- data/lib/state_machine/integrations/active_model.rb +14 -20
- data/lib/state_machine/integrations/active_model/observer.rb +3 -3
- data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
- data/lib/state_machine/integrations/active_record.rb +52 -25
- data/lib/state_machine/integrations/active_record/locale.rb +1 -1
- data/lib/state_machine/integrations/active_record/versions.rb +1 -17
- data/lib/state_machine/integrations/base.rb +15 -6
- data/lib/state_machine/integrations/data_mapper.rb +98 -35
- data/lib/state_machine/integrations/data_mapper/versions.rb +46 -8
- data/lib/state_machine/integrations/mongo_mapper.rb +39 -12
- data/lib/state_machine/integrations/mongo_mapper/locale.rb +1 -1
- data/lib/state_machine/integrations/mongo_mapper/versions.rb +3 -20
- data/lib/state_machine/integrations/mongoid.rb +52 -14
- data/lib/state_machine/integrations/mongoid/locale.rb +1 -1
- data/lib/state_machine/integrations/mongoid/versions.rb +52 -26
- data/lib/state_machine/integrations/sequel.rb +82 -33
- data/lib/state_machine/integrations/sequel/versions.rb +19 -44
- data/lib/state_machine/machine.rb +99 -59
- data/lib/state_machine/machine_collection.rb +1 -2
- data/lib/state_machine/macro_methods.rb +29 -0
- data/lib/state_machine/node_collection.rb +1 -1
- data/lib/state_machine/state.rb +18 -10
- data/lib/state_machine/state_context.rb +2 -2
- data/lib/state_machine/transition.rb +8 -1
- data/lib/state_machine/transition_collection.rb +2 -1
- data/lib/state_machine/version.rb +1 -1
- data/lib/state_machine/yard.rb +8 -0
- data/lib/state_machine/yard/handlers.rb +12 -0
- data/lib/state_machine/yard/handlers/base.rb +32 -0
- data/lib/state_machine/yard/handlers/event.rb +25 -0
- data/lib/state_machine/yard/handlers/machine.rb +344 -0
- data/lib/state_machine/yard/handlers/state.rb +25 -0
- data/lib/state_machine/yard/handlers/transition.rb +47 -0
- data/lib/state_machine/yard/templates.rb +3 -0
- data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
- data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
- data/lib/tasks/state_machine.rb +2 -1
- data/lib/yard-state_machine.rb +2 -0
- data/state_machine.gemspec +4 -3
- data/test/files/switch.rb +4 -0
- data/test/test_helper.rb +5 -0
- data/test/unit/branch_test.rb +117 -36
- data/test/unit/callback_test.rb +5 -2
- data/test/unit/eval_helpers_test.rb +49 -1
- data/test/unit/event_collection_test.rb +3 -1
- data/test/unit/event_test.rb +182 -12
- data/test/unit/graph_test.rb +98 -0
- data/test/unit/integrations/active_model_test.rb +82 -12
- data/test/unit/integrations/active_record_test.rb +393 -37
- data/test/unit/integrations/base_test.rb +7 -2
- data/test/unit/integrations/data_mapper_test.rb +326 -72
- data/test/unit/integrations/mongo_mapper_test.rb +338 -44
- data/test/unit/integrations/mongoid_test.rb +606 -98
- data/test/unit/integrations/sequel_test.rb +429 -102
- data/test/unit/integrations_test.rb +28 -6
- data/test/unit/machine_collection_test.rb +6 -2
- data/test/unit/machine_test.rb +134 -82
- data/test/unit/node_collection_test.rb +2 -2
- data/test/unit/path_test.rb +1 -1
- data/test/unit/state_test.rb +65 -21
- data/test/unit/transition_collection_test.rb +43 -23
- data/test/unit/transition_test.rb +8 -2
- metadata +303 -221
- data/gemfiles/active_model-3.2.0.gemfile.lock +0 -32
- data/gemfiles/active_record-3.2.0.gemfile.lock +0 -43
- data/gemfiles/graphviz-0.9.0.gemfile.lock +0 -26
@@ -283,6 +283,22 @@ module StateMachine
|
|
283
283
|
# end
|
284
284
|
# end
|
285
285
|
#
|
286
|
+
# === Callback Order
|
287
|
+
#
|
288
|
+
# Callbacks occur in the following order. Callbacks specific to state_machine
|
289
|
+
# are bolded. The remaining callbacks are part of Mongoid.
|
290
|
+
#
|
291
|
+
# * (-) save
|
292
|
+
# * (1) *before_transition*
|
293
|
+
# * (-) valid
|
294
|
+
# * (2) before_validation
|
295
|
+
# * (3) after_validation
|
296
|
+
# * (4) before_save
|
297
|
+
# * (5) before_create
|
298
|
+
# * (6) after_create
|
299
|
+
# * (7) after_save
|
300
|
+
# * (8) *after_transition*
|
301
|
+
#
|
286
302
|
# == Internationalization
|
287
303
|
#
|
288
304
|
# Any error message that is generated from performing invalid transitions
|
@@ -341,17 +357,10 @@ module StateMachine
|
|
341
357
|
# The default options to use for state machines using this integration
|
342
358
|
@defaults = {:action => :save}
|
343
359
|
|
344
|
-
# Whether this integration is available. Only true if Mongoid::Document
|
345
|
-
# is defined.
|
346
|
-
def self.available?
|
347
|
-
defined?(::Mongoid::Document)
|
348
|
-
end
|
349
|
-
|
350
|
-
# Should this integration be used for state machines in the given class?
|
351
360
|
# Classes that include Mongoid::Document will automatically use the
|
352
361
|
# Mongoid integration.
|
353
|
-
def self.
|
354
|
-
|
362
|
+
def self.matching_ancestors
|
363
|
+
%w(Mongoid::Document)
|
355
364
|
end
|
356
365
|
|
357
366
|
def self.extended(base) #:nodoc:
|
@@ -365,33 +374,62 @@ module StateMachine
|
|
365
374
|
action == :save
|
366
375
|
end
|
367
376
|
|
377
|
+
# Gets the db default for the machine's attribute
|
378
|
+
def owner_class_attribute_default
|
379
|
+
attribute_field && attribute_field.default_val
|
380
|
+
end
|
381
|
+
|
382
|
+
# Gets the field for this machine's attribute (if it exists)
|
383
|
+
def attribute_field
|
384
|
+
owner_class.fields[attribute.to_s] || owner_class.fields[owner_class.aliased_fields[attribute.to_s]]
|
385
|
+
end
|
386
|
+
|
368
387
|
# Defines an initialization hook into the owner class for setting the
|
369
388
|
# initial state of the machine *before* any attributes are set on the
|
370
389
|
# object
|
371
390
|
def define_state_initializer
|
372
391
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
373
392
|
def initialize(*)
|
374
|
-
@attributes ||= {}
|
375
|
-
self.class.state_machines.initialize_states(self, :dynamic => false)
|
376
|
-
|
377
393
|
super do |*args|
|
378
394
|
self.class.state_machines.initialize_states(self, :static => false)
|
379
395
|
yield(*args) if block_given?
|
380
396
|
end
|
381
397
|
end
|
398
|
+
|
399
|
+
def apply_pre_processed_defaults
|
400
|
+
defaults = {}
|
401
|
+
self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false, :to => defaults)
|
402
|
+
defaults.each do |attr, value|
|
403
|
+
send(:"\#{attr}=", value) unless attributes.include?(attr)
|
404
|
+
end
|
405
|
+
super
|
406
|
+
end
|
382
407
|
end_eval
|
383
408
|
end
|
384
409
|
|
385
410
|
# Skips defining reader/writer methods since this is done automatically
|
386
411
|
def define_state_accessor
|
387
|
-
owner_class.field(attribute, :type => String) unless
|
412
|
+
owner_class.field(attribute, :type => String) unless attribute_field
|
388
413
|
super
|
389
414
|
end
|
390
415
|
|
391
416
|
# Uses around callbacks to run state events if using the :save hook
|
392
417
|
def define_action_hook
|
393
418
|
if action_hook == :save
|
394
|
-
|
419
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
420
|
+
def insert(*)
|
421
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super.persisted? }
|
422
|
+
self
|
423
|
+
end
|
424
|
+
|
425
|
+
def update(*)
|
426
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
|
427
|
+
end
|
428
|
+
|
429
|
+
def upsert(*)
|
430
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
|
431
|
+
end
|
432
|
+
end_eval
|
395
433
|
else
|
396
434
|
super
|
397
435
|
end
|
@@ -1,4 +1,4 @@
|
|
1
1
|
filename = "#{File.dirname(__FILE__)}/../active_model/locale.rb"
|
2
|
-
translations = eval(IO.read(filename), binding, filename)
|
2
|
+
translations = eval(IO.read(File.expand_path(filename)), binding, filename)
|
3
3
|
translations[:en][:mongoid] = translations[:en].delete(:activemodel)
|
4
4
|
translations
|
@@ -1,53 +1,79 @@
|
|
1
1
|
module StateMachine
|
2
2
|
module Integrations #:nodoc:
|
3
3
|
module Mongoid
|
4
|
-
version '2.
|
4
|
+
version '2.x' do
|
5
5
|
def self.active?
|
6
|
-
::Mongoid::VERSION =~ /^2
|
6
|
+
::Mongoid::VERSION =~ /^2\./
|
7
7
|
end
|
8
8
|
|
9
9
|
def define_state_initializer
|
10
10
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
11
|
-
# Initializes dynamic states
|
12
11
|
def initialize(*)
|
12
|
+
@attributes ||= {}
|
13
|
+
self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false)
|
14
|
+
|
13
15
|
super do |*args|
|
14
16
|
self.class.state_machines.initialize_states(self, :static => false)
|
15
17
|
yield(*args) if block_given?
|
16
18
|
end
|
17
19
|
end
|
18
|
-
|
19
|
-
# Initializes static states
|
20
|
-
def apply_default_attributes(*)
|
21
|
-
result = super
|
22
|
-
self.class.state_machines.initialize_states(self, :dynamic => false, :to => result) if new_record?
|
23
|
-
result
|
24
|
-
end
|
25
20
|
end_eval
|
26
21
|
end
|
27
22
|
|
23
|
+
def owner_class_attribute_default
|
24
|
+
attribute_field && attribute_field.default
|
25
|
+
end
|
26
|
+
|
28
27
|
def define_action_hook
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
if action_hook == :save
|
29
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
30
|
+
def insert(*)
|
31
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super.persisted? }
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def update(*)
|
36
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
|
37
|
+
end
|
38
|
+
end_eval
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
35
|
-
version '2.0.x' do
|
45
|
+
version '2.0.x - 2.3.x' do
|
36
46
|
def self.active?
|
37
|
-
::Mongoid::VERSION =~ /^2\.0\./
|
47
|
+
::Mongoid::VERSION =~ /^2\.[0-3]\./
|
38
48
|
end
|
39
49
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
def attribute_field
|
51
|
+
owner_class.fields[attribute.to_s]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
version '2.0.x - 2.2.x' do
|
56
|
+
def self.active?
|
57
|
+
::Mongoid::VERSION =~ /^2\.[0-2]\./
|
58
|
+
end
|
59
|
+
|
60
|
+
def define_state_initializer
|
61
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
62
|
+
# Initializes dynamic states
|
63
|
+
def initialize(*)
|
64
|
+
super do |*args|
|
65
|
+
self.class.state_machines.initialize_states(self, :static => false)
|
66
|
+
yield(*args) if block_given?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Initializes static states
|
71
|
+
def apply_default_attributes(*)
|
72
|
+
result = super
|
73
|
+
self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false, :to => result) if new_record?
|
74
|
+
result
|
75
|
+
end
|
76
|
+
end_eval
|
51
77
|
end
|
52
78
|
end
|
53
79
|
end
|
@@ -134,18 +134,6 @@ module StateMachine
|
|
134
134
|
# end
|
135
135
|
# end
|
136
136
|
#
|
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+. 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
|
148
|
-
#
|
149
137
|
# == Validation errors
|
150
138
|
#
|
151
139
|
# If an event fails to successfully fire because there are no matching
|
@@ -265,26 +253,38 @@ module StateMachine
|
|
265
253
|
# The +TransitionLog+ model uses a second connection to the database that
|
266
254
|
# allows new records to be saved without being affected by rollbacks in the
|
267
255
|
# +Vehicle+ model's transaction.
|
256
|
+
#
|
257
|
+
# === Callback Order
|
258
|
+
#
|
259
|
+
# Callbacks occur in the following order. Callbacks specific to state_machine
|
260
|
+
# are bolded. The remaining callbacks are part of Sequel.
|
261
|
+
#
|
262
|
+
# * (-) save
|
263
|
+
# * (-) begin transaction (if enabled)
|
264
|
+
# * (1) *before_transition*
|
265
|
+
# * (2) before_validation
|
266
|
+
# * (-) validate
|
267
|
+
# * (3) after_validation
|
268
|
+
# * (4) before_save
|
269
|
+
# * (5) before_create
|
270
|
+
# * (-) create
|
271
|
+
# * (6) after_create
|
272
|
+
# * (7) after_save
|
273
|
+
# * (8) *after_transition*
|
274
|
+
# * (-) end transaction (if enabled)
|
275
|
+
# * (9) after_commit
|
268
276
|
module Sequel
|
269
277
|
include Base
|
270
278
|
|
271
279
|
require 'state_machine/integrations/sequel/versions'
|
272
280
|
|
273
281
|
# The default options to use for state machines using this integration
|
274
|
-
class << self; attr_reader :defaults; end
|
275
282
|
@defaults = {:action => :save}
|
276
283
|
|
277
|
-
# Whether this integration is available. Only true if Sequel::Model is
|
278
|
-
# defined.
|
279
|
-
def self.available?
|
280
|
-
defined?(::Sequel::Model)
|
281
|
-
end
|
282
|
-
|
283
|
-
# Should this integration be used for state machines in the given class?
|
284
284
|
# Classes that include Sequel::Model will automatically use the Sequel
|
285
285
|
# integration.
|
286
|
-
def self.
|
287
|
-
|
286
|
+
def self.matching_ancestors
|
287
|
+
%w(Sequel::Model)
|
288
288
|
end
|
289
289
|
|
290
290
|
# Forces the change in state to be recognized regardless of whether the
|
@@ -331,7 +331,6 @@ module StateMachine
|
|
331
331
|
|
332
332
|
# Loads all of the Sequel plugins necessary to run
|
333
333
|
def load_plugins
|
334
|
-
owner_class.plugin(:validation_class_methods)
|
335
334
|
owner_class.plugin(:hook_class_methods)
|
336
335
|
end
|
337
336
|
|
@@ -346,18 +345,20 @@ module StateMachine
|
|
346
345
|
def define_state_initializer
|
347
346
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
348
347
|
def initialize_set(*)
|
349
|
-
self.class.state_machines.initialize_states(self) { super }
|
348
|
+
self.class.state_machines.initialize_states(self, :static => :force) { super }
|
350
349
|
end
|
351
350
|
end_eval
|
352
351
|
end
|
353
352
|
|
354
353
|
# Skips defining reader/writer methods since this is done automatically
|
355
354
|
def define_state_accessor
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
355
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
356
|
+
def validate(*)
|
357
|
+
super
|
358
|
+
machine = self.class.state_machine(#{name.inspect})
|
359
|
+
machine.invalidate(self, :state, :invalid) unless machine.states.match(self)
|
360
|
+
end
|
361
|
+
end_eval
|
361
362
|
end
|
362
363
|
|
363
364
|
# Defines validation hooks if the machine's action is to save the model
|
@@ -366,6 +367,43 @@ module StateMachine
|
|
366
367
|
define_validation_hook if action == :save
|
367
368
|
end
|
368
369
|
|
370
|
+
# Uses around callbacks to run state events if using the :save hook
|
371
|
+
def define_action_hook
|
372
|
+
if action == :save
|
373
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
374
|
+
def #{action_hook}(*args)
|
375
|
+
opts = args.last.is_a?(Hash) ? args.last : {}
|
376
|
+
yielded = false
|
377
|
+
result = self.class.state_machine(#{name.inspect}).send(:around_save, self) do
|
378
|
+
yielded = true
|
379
|
+
super
|
380
|
+
end
|
381
|
+
|
382
|
+
if yielded || result
|
383
|
+
result
|
384
|
+
else
|
385
|
+
#{handle_save_failure}
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end_eval
|
389
|
+
else
|
390
|
+
super
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
# Handles how save failures (due to invalid transitions) are raised
|
395
|
+
def handle_save_failure
|
396
|
+
'raise_hook_failure(:before_transition) if raise_on_failure?(opts)'
|
397
|
+
end
|
398
|
+
|
399
|
+
# Runs state events around the machine's :save action
|
400
|
+
def around_save(object)
|
401
|
+
result = transaction(object) do
|
402
|
+
object.class.state_machines.transitions(object, action).perform { yield }
|
403
|
+
end
|
404
|
+
result
|
405
|
+
end
|
406
|
+
|
369
407
|
# Adds hooks into validation for automatically firing events
|
370
408
|
def define_validation_hook
|
371
409
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
@@ -375,9 +413,16 @@ module StateMachine
|
|
375
413
|
end_eval
|
376
414
|
end
|
377
415
|
|
378
|
-
#
|
379
|
-
def
|
380
|
-
|
416
|
+
# Gets the db default for the machine's attribute
|
417
|
+
def owner_class_attribute_default
|
418
|
+
if owner_class.db.table_exists?(owner_class.table_name) && column = owner_class.db_schema[attribute.to_sym]
|
419
|
+
column[:default]
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
# Uses the DB literal to match the default against the specified state
|
424
|
+
def owner_class_attribute_default_matches?(state)
|
425
|
+
owner_class.db.literal(state.value) == owner_class_attribute_default
|
381
426
|
end
|
382
427
|
|
383
428
|
# Creates a scope for finding records *with* a particular state or
|
@@ -421,7 +466,11 @@ module StateMachine
|
|
421
466
|
# Runs a new database transaction, rolling back any changes if the
|
422
467
|
# yielded block fails (i.e. returns false).
|
423
468
|
def transaction(object)
|
424
|
-
|
469
|
+
result = nil
|
470
|
+
object.db.transaction do
|
471
|
+
raise ::Sequel::Error::Rollback unless result = yield
|
472
|
+
end
|
473
|
+
result
|
425
474
|
end
|
426
475
|
|
427
476
|
# Creates a new callback in the callback chain, always ensuring that
|
@@ -17,7 +17,7 @@ module StateMachine
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def set(*)
|
20
|
-
self.class.state_machines.initialize_states(self, :dynamic => false) if values.empty?
|
20
|
+
self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false) if values.empty?
|
21
21
|
super
|
22
22
|
end
|
23
23
|
end_eval
|
@@ -26,6 +26,7 @@ module StateMachine
|
|
26
26
|
def define_validation_hook
|
27
27
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
28
28
|
def valid?(*args)
|
29
|
+
opts = args.first.is_a?(Hash) ? args.first : {}
|
29
30
|
yielded = false
|
30
31
|
result = self.class.state_machines.transitions(self, :save, :after => false).perform do
|
31
32
|
yielded = true
|
@@ -40,31 +41,19 @@ module StateMachine
|
|
40
41
|
end
|
41
42
|
end_eval
|
42
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
version '2.8.x - 3.13.x' do
|
47
|
+
def self.active?
|
48
|
+
!defined?(::Sequel::MAJOR) || ::Sequel::MAJOR == 2 || ::Sequel::MAJOR == 3 && ::Sequel::MINOR <= 13
|
49
|
+
end
|
43
50
|
|
44
|
-
def
|
45
|
-
|
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
|
51
|
+
def handle_validation_failure
|
52
|
+
'raise_on_save_failure ? save_failure(:validation) : result'
|
64
53
|
end
|
65
54
|
|
66
|
-
def
|
67
|
-
|
55
|
+
def handle_save_failure
|
56
|
+
'save_failure(:save) if raise_on_save_failure'
|
68
57
|
end
|
69
58
|
end
|
70
59
|
|
@@ -79,26 +68,16 @@ module StateMachine
|
|
79
68
|
def load_inflector
|
80
69
|
end
|
81
70
|
|
82
|
-
def action_hook
|
83
|
-
action == :save ? :save : super
|
84
|
-
end
|
85
|
-
|
86
71
|
def model_from_dataset(dataset)
|
87
72
|
dataset.model_classes[nil]
|
88
73
|
end
|
89
|
-
end
|
90
|
-
|
91
|
-
version '2.8.x - 3.13.x' do
|
92
|
-
def self.active?
|
93
|
-
!defined?(::Sequel::MAJOR) || ::Sequel::MAJOR == 2 || ::Sequel::MAJOR == 3 && ::Sequel::MINOR <= 13
|
94
|
-
end
|
95
|
-
|
96
|
-
def handle_validation_failure
|
97
|
-
'raise_on_save_failure ? save_failure(:validation) : result'
|
98
|
-
end
|
99
74
|
|
100
|
-
def
|
101
|
-
|
75
|
+
def define_state_accessor
|
76
|
+
name = self.name
|
77
|
+
owner_class.validates_each(attribute) do |record, attr, value|
|
78
|
+
machine = record.class.state_machine(name)
|
79
|
+
machine.invalidate(record, :state, :invalid) unless machine.states.match(record)
|
80
|
+
end
|
102
81
|
end
|
103
82
|
end
|
104
83
|
|
@@ -108,11 +87,7 @@ module StateMachine
|
|
108
87
|
end
|
109
88
|
|
110
89
|
def handle_validation_failure
|
111
|
-
'raise_on_failure?(
|
112
|
-
end
|
113
|
-
|
114
|
-
def handle_save_failure
|
115
|
-
'raise_hook_failure(:save)'
|
90
|
+
'raise_on_failure?(opts) ? raise_hook_failure(:validation) : result'
|
116
91
|
end
|
117
92
|
end
|
118
93
|
end
|