aasm 4.11.1 → 4.12.1

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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +19 -16
  3. data/Appraisals +46 -0
  4. data/CHANGELOG.md +19 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +4 -21
  7. data/README.md +154 -39
  8. data/Rakefile +6 -1
  9. data/TESTING.md +25 -0
  10. data/aasm.gemspec +3 -0
  11. data/gemfiles/rails_3.2.gemfile +13 -0
  12. data/gemfiles/rails_4.0.gemfile +8 -9
  13. data/gemfiles/rails_4.2.gemfile +10 -9
  14. data/gemfiles/rails_4.2_mongoid_5.gemfile +5 -9
  15. data/gemfiles/rails_5.0.gemfile +8 -16
  16. data/lib/aasm/aasm.rb +9 -3
  17. data/lib/aasm/base.rb +11 -1
  18. data/lib/aasm/configuration.rb +4 -0
  19. data/lib/aasm/core/event.rb +18 -4
  20. data/lib/aasm/core/state.rb +7 -0
  21. data/lib/aasm/core/transition.rb +10 -1
  22. data/lib/aasm/instance_base.rb +0 -2
  23. data/lib/aasm/minitest/allow_event.rb +13 -0
  24. data/lib/aasm/minitest/allow_transition_to.rb +13 -0
  25. data/lib/aasm/minitest/have_state.rb +13 -0
  26. data/lib/aasm/minitest/transition_from.rb +21 -0
  27. data/lib/aasm/minitest.rb +5 -0
  28. data/lib/aasm/minitest_spec.rb +15 -0
  29. data/lib/aasm/persistence/active_record_persistence.rb +25 -101
  30. data/lib/aasm/persistence/base.rb +7 -3
  31. data/lib/aasm/persistence/mongoid_persistence.rb +25 -31
  32. data/lib/aasm/persistence/orm.rb +142 -0
  33. data/lib/aasm/persistence/redis_persistence.rb +16 -11
  34. data/lib/aasm/persistence/sequel_persistence.rb +36 -63
  35. data/lib/aasm/persistence.rb +0 -3
  36. data/lib/aasm/state_machine.rb +4 -2
  37. data/lib/aasm/state_machine_store.rb +5 -2
  38. data/lib/aasm/version.rb +1 -1
  39. data/lib/generators/active_record/templates/migration.rb +1 -1
  40. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  41. data/lib/motion-aasm.rb +2 -1
  42. data/spec/generators/active_record_generator_spec.rb +42 -39
  43. data/spec/generators/mongoid_generator_spec.rb +4 -6
  44. data/spec/models/active_record/complex_active_record_example.rb +5 -1
  45. data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
  46. data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
  47. data/spec/models/{transactor.rb → active_record/transactor.rb} +0 -2
  48. data/spec/models/{validator.rb → active_record/validator.rb} +0 -2
  49. data/spec/models/callbacks/basic.rb +5 -2
  50. data/spec/models/guard_with_params.rb +1 -1
  51. data/spec/models/guardian_without_from_specified.rb +18 -0
  52. data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
  53. data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
  54. data/spec/models/mongoid/validator_mongoid.rb +100 -0
  55. data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
  56. data/spec/models/namespaced_multiple_example.rb +14 -0
  57. data/spec/models/parametrised_event.rb +7 -0
  58. data/spec/models/{mongo_mapper/complex_mongo_mapper_example.rb → redis/complex_redis_example.rb} +8 -5
  59. data/spec/models/redis/redis_multiple.rb +20 -0
  60. data/spec/models/redis/redis_simple.rb +20 -0
  61. data/spec/models/sequel/complex_sequel_example.rb +4 -3
  62. data/spec/models/sequel/invalid_persistor.rb +52 -0
  63. data/spec/models/sequel/sequel_multiple.rb +13 -13
  64. data/spec/models/sequel/sequel_simple.rb +13 -12
  65. data/spec/models/sequel/silent_persistor.rb +50 -0
  66. data/spec/models/sequel/transactor.rb +112 -0
  67. data/spec/models/sequel/validator.rb +93 -0
  68. data/spec/models/sequel/worker.rb +12 -0
  69. data/spec/models/simple_multiple_example.rb +12 -0
  70. data/spec/models/sub_class.rb +34 -0
  71. data/spec/spec_helper.rb +0 -33
  72. data/spec/spec_helpers/active_record.rb +7 -0
  73. data/spec/spec_helpers/dynamoid.rb +33 -0
  74. data/spec/spec_helpers/mongoid.rb +7 -0
  75. data/spec/spec_helpers/redis.rb +15 -0
  76. data/spec/spec_helpers/remove_warnings.rb +1 -0
  77. data/spec/spec_helpers/sequel.rb +7 -0
  78. data/spec/unit/api_spec.rb +76 -73
  79. data/spec/unit/callbacks_spec.rb +5 -0
  80. data/spec/unit/event_spec.rb +12 -0
  81. data/spec/unit/guard_spec.rb +17 -0
  82. data/spec/unit/guard_with_params_spec.rb +4 -0
  83. data/spec/unit/guard_without_from_specified_spec.rb +10 -0
  84. data/spec/unit/localizer_spec.rb +55 -53
  85. data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
  86. data/spec/unit/namespaced_multiple_example_spec.rb +22 -0
  87. data/spec/unit/override_warning_spec.rb +8 -0
  88. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +453 -449
  89. data/spec/unit/persistence/active_record_persistence_spec.rb +524 -502
  90. data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
  91. data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
  92. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +83 -9
  93. data/spec/unit/persistence/mongoid_persistence_spec.rb +85 -9
  94. data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
  95. data/spec/unit/persistence/redis_persistence_spec.rb +8 -32
  96. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +6 -11
  97. data/spec/unit/persistence/sequel_persistence_spec.rb +278 -10
  98. data/spec/unit/simple_multiple_example_spec.rb +28 -0
  99. data/spec/unit/subclassing_multiple_spec.rb +37 -2
  100. data/spec/unit/subclassing_spec.rb +17 -2
  101. data/test/minitest_helper.rb +57 -0
  102. data/test/unit/minitest_matcher_test.rb +80 -0
  103. metadata +99 -28
  104. data/gemfiles/rails_3.2_stable.gemfile +0 -15
  105. data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -16
  106. data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -17
  107. data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
  108. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
  109. data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
  110. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
  111. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -149
  112. data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -96
  113. /data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
@@ -0,0 +1,39 @@
1
+ class SilentPersistorMongoid
2
+ include Mongoid::Document
3
+ include AASM
4
+
5
+ field :name
6
+ field :status
7
+
8
+ aasm :left, column: :status, whiny_persistence: false do
9
+ state :sleeping, :initial => true
10
+ state :running
11
+ event :run do
12
+ transitions :to => :running, :from => :sleeping
13
+ end
14
+ event :sleep do
15
+ transitions :to => :sleeping, :from => :running
16
+ end
17
+ end
18
+ validates_presence_of :name
19
+ end
20
+
21
+ class MultipleSilentPersistorMongoid
22
+ include Mongoid::Document
23
+ include AASM
24
+
25
+ field :name
26
+ field :status
27
+
28
+ aasm :left, column: :status, whiny_persistence: false do
29
+ state :sleeping, :initial => true
30
+ state :running
31
+ event :run do
32
+ transitions :to => :running, :from => :sleeping
33
+ end
34
+ event :sleep do
35
+ transitions :to => :sleeping, :from => :running
36
+ end
37
+ end
38
+ validates_presence_of :name
39
+ end
@@ -0,0 +1,100 @@
1
+ class ValidatorMongoid
2
+ include Mongoid::Document
3
+ include AASM
4
+
5
+ field :name
6
+ field :status
7
+
8
+ attr_accessor :invalid
9
+
10
+ validate do |model|
11
+ errors.add(:validator, "invalid") if invalid
12
+ end
13
+
14
+ include AASM
15
+
16
+ aasm :column => :status, :whiny_persistence => true do
17
+ before_all_transactions :before_all_transactions
18
+ after_all_transactions :after_all_transactions
19
+
20
+ state :sleeping, :initial => true
21
+ state :running
22
+ state :failed, :after_enter => :fail
23
+
24
+ event :run, :after_commit => :change_name! do
25
+ transitions :to => :running, :from => :sleeping
26
+ end
27
+
28
+ event :sleep do
29
+ after_commit do |name|
30
+ change_name_on_sleep name
31
+ end
32
+ transitions :to => :sleeping, :from => :running
33
+ end
34
+
35
+ event :fail do
36
+ transitions :to => :failed, :from => [:sleeping, :running]
37
+ end
38
+ end
39
+
40
+ validates_presence_of :name
41
+
42
+ def change_name!
43
+ self.name = "name changed"
44
+ save!
45
+ end
46
+
47
+ def change_name_on_sleep name
48
+ self.name = name
49
+ save!
50
+ end
51
+
52
+ def fail
53
+ raise StandardError.new('failed on purpose')
54
+ end
55
+ end
56
+
57
+ class MultipleValidatorMongoid
58
+ include Mongoid::Document
59
+ include AASM
60
+
61
+ field :name
62
+ field :status
63
+
64
+ attr_accessor :invalid
65
+
66
+ aasm :left, :column => :status, :whiny_persistence => true do
67
+ state :sleeping, :initial => true
68
+ state :running
69
+ state :failed, :after_enter => :fail
70
+
71
+ event :run, :after_commit => :change_name! do
72
+ transitions :to => :running, :from => :sleeping
73
+ end
74
+ event :sleep do
75
+ after_commit do |name|
76
+ change_name_on_sleep name
77
+ end
78
+ transitions :to => :sleeping, :from => :running
79
+ end
80
+ event :fail do
81
+ transitions :to => :failed, :from => [:sleeping, :running]
82
+ end
83
+ end
84
+
85
+ validates_presence_of :name
86
+
87
+ def change_name!
88
+ self.name = "name changed"
89
+ save!
90
+ end
91
+
92
+ def change_name_on_sleep name
93
+ self.name = name
94
+ save!
95
+ end
96
+
97
+ def fail
98
+ raise StandardError.new('failed on purpose')
99
+ end
100
+ end
@@ -0,0 +1,31 @@
1
+ class MultipleTransitionsThatDifferOnlyByGuard
2
+ include AASM
3
+
4
+ attr_accessor :executed_second
5
+
6
+ aasm do
7
+ state :start, :initial => true
8
+ state :gone
9
+
10
+ event :go do
11
+ transitions :from => :start, :to => :gone, :guard => :returns_false, :after => :this_should_not_execute
12
+ transitions :from => :start, :to => :gone, :guard => :returns_true, :after => :this_should_execute
13
+ end
14
+ end
15
+
16
+ def returns_false
17
+ false
18
+ end
19
+
20
+ def returns_true
21
+ true
22
+ end
23
+
24
+ def this_should_not_execute
25
+ raise RuntimeError, "This should not execute"
26
+ end
27
+
28
+ def this_should_execute
29
+ self.executed_second = true
30
+ end
31
+ end
@@ -25,4 +25,18 @@ class NamespacedMultipleExample
25
25
  transitions :from => :approved, :to => :unapproved
26
26
  end
27
27
  end
28
+
29
+ # Test namespace event methods with suffix (ie may_sell_car?, sell_car!)
30
+ aasm(:car, namespace: :car) do
31
+ state :unsold, :initial => true
32
+ state :sold
33
+
34
+ event :sell do
35
+ transitions :from => :unsold, :to => :sold
36
+ end
37
+
38
+ event :return do
39
+ transitions :from => :sold, :to => :unsold
40
+ end
41
+ end
28
42
  end
@@ -11,6 +11,10 @@ class ParametrisedEvent
11
11
  transitions :from => :sleeping, :to => [:showering, :working]
12
12
  end
13
13
 
14
+ event :shower do
15
+ transitions :from => :sleeping, :to => :showering, :after => :wet_hair, :success => :wear_clothes
16
+ end
17
+
14
18
  event :dress do
15
19
  transitions :from => :sleeping, :to => :working, :after => :wear_clothes, :success => :wear_makeup
16
20
  transitions :from => :showering, :to => [:working, :dating], :after => Proc.new { |*args| wear_clothes(*args) }, :success => proc { |*args| wear_makeup(*args) }
@@ -24,6 +28,9 @@ class ParametrisedEvent
24
28
  def wear_makeup(makeup, moisturizer)
25
29
  end
26
30
 
31
+ def wet_hair(dryer)
32
+ end
33
+
27
34
  def condition_hair
28
35
  end
29
36
 
@@ -1,9 +1,13 @@
1
- class ComplexMongoMapperExample
2
- include MongoMapper::Document
1
+ class RedisComplexExample
2
+ include Redis::Objects
3
3
  include AASM
4
4
 
5
- key :left, String
6
- key :right, String
5
+ value :left
6
+ value :right
7
+
8
+ def id
9
+ 1
10
+ end
7
11
 
8
12
  aasm :left, :column => 'left' do
9
13
  state :one, :initial => true
@@ -33,5 +37,4 @@ class ComplexMongoMapperExample
33
37
  transitions :from => :beta, :to => :alpha
34
38
  end
35
39
  end
36
-
37
40
  end
@@ -0,0 +1,20 @@
1
+ class RedisMultiple
2
+ include Redis::Objects
3
+ include AASM
4
+
5
+ value :status
6
+
7
+ def id
8
+ 1
9
+ end
10
+
11
+ aasm :left, :column => :status
12
+ aasm :left do
13
+ state :alpha, :initial => true
14
+ state :beta
15
+ state :gamma
16
+ event :release do
17
+ transitions :from => [:alpha, :beta, :gamma], :to => :beta
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ class RedisSimple
2
+ include Redis::Objects
3
+ include AASM
4
+
5
+ value :status
6
+
7
+ def id
8
+ 1
9
+ end
10
+
11
+ aasm :column => :status
12
+ aasm do
13
+ state :alpha, :initial => true
14
+ state :beta
15
+ state :gamma
16
+ event :release do
17
+ transitions :from => [:alpha, :beta, :gamma], :to => :beta
18
+ end
19
+ end
20
+ end
@@ -1,4 +1,4 @@
1
- db = Sequel.connect(SEQUEL_DB)
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
2
 
3
3
  # if you want to see the statements while running the spec enable the following line
4
4
  # db.loggers << Logger.new($stderr)
@@ -8,8 +8,8 @@ db.create_table(:complex_sequel_examples) do
8
8
  String :right
9
9
  end
10
10
 
11
- class ComplexSequelExample < Sequel::Model(db)
12
- set_dataset(:complex_sequel_examples)
11
+ module Sequel
12
+ class ComplexExample < Sequel::Model(:complex_sequel_examples)
13
13
 
14
14
  include AASM
15
15
 
@@ -43,3 +43,4 @@ class ComplexSequelExample < Sequel::Model(db)
43
43
  end
44
44
 
45
45
  end
46
+ end
@@ -0,0 +1,52 @@
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
+
3
+ [:invalid_persistors, :multiple_invalid_persistors].each do |table_name|
4
+ db.create_table(table_name) do
5
+ primary_key :id
6
+ String "name"
7
+ String "status"
8
+ end
9
+ end
10
+
11
+ module Sequel
12
+ class InvalidPersistor < Sequel::Model(:invalid_persistors)
13
+ plugin :validation_helpers
14
+
15
+ include AASM
16
+ aasm :column => :status, :skip_validation_on_save => true do
17
+ state :sleeping, :initial => true
18
+ state :running
19
+ event :run do
20
+ transitions :to => :running, :from => :sleeping
21
+ end
22
+ event :sleep do
23
+ transitions :to => :sleeping, :from => :running
24
+ end
25
+ end
26
+
27
+ def validate
28
+ super
29
+ validates_presence :name
30
+ end
31
+ end
32
+
33
+ class MultipleInvalidPersistor < Sequel::Model(:multiple_invalid_persistors)
34
+ plugin :validation_helpers
35
+
36
+ include AASM
37
+ aasm :left, :column => :status, :skip_validation_on_save => true do
38
+ state :sleeping, :initial => true
39
+ state :running
40
+ event :run do
41
+ transitions :to => :running, :from => :sleeping
42
+ end
43
+ event :sleep do
44
+ transitions :to => :sleeping, :from => :running
45
+ end
46
+ end
47
+ def validate
48
+ super
49
+ validates_presence :name
50
+ end
51
+ end
52
+ end
@@ -1,4 +1,4 @@
1
- db = Sequel.connect(SEQUEL_DB)
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
2
 
3
3
  # if you want to see the statements while running the spec enable the following line
4
4
  # db.loggers << Logger.new($stderr)
@@ -6,20 +6,20 @@ db.create_table(:multiples) do
6
6
  primary_key :id
7
7
  String :status
8
8
  end
9
+ module Sequel
10
+ class Multiple < Sequel::Model(:multiples)
11
+ include AASM
9
12
 
10
- class SequelMultiple < Sequel::Model(db)
11
- set_dataset(:multiples)
12
- include AASM
13
+ attr_accessor :default
13
14
 
14
- attr_accessor :default
15
-
16
- aasm :left, :column => :status
17
- aasm :left do
18
- state :alpha, :initial => true
19
- state :beta
20
- state :gamma
21
- event :release do
22
- transitions :from => [:alpha, :beta, :gamma], :to => :beta
15
+ aasm :left, :column => :status
16
+ aasm :left do
17
+ state :alpha, :initial => true
18
+ state :beta
19
+ state :gamma
20
+ event :release do
21
+ transitions :from => [:alpha, :beta, :gamma], :to => :beta
22
+ end
23
23
  end
24
24
  end
25
25
  end
@@ -1,4 +1,4 @@
1
- db = Sequel.connect(SEQUEL_DB)
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
2
 
3
3
  # if you want to see the statements while running the spec enable the following line
4
4
  # db.loggers << Logger.new($stderr)
@@ -7,19 +7,20 @@ db.create_table(:simples) do
7
7
  String :status
8
8
  end
9
9
 
10
- class SequelSimple < Sequel::Model(db)
11
- set_dataset(:simples)
12
- include AASM
10
+ module Sequel
11
+ class Simple < Sequel::Model(:simples)
12
+ include AASM
13
13
 
14
- attr_accessor :default
14
+ attr_accessor :default
15
15
 
16
- aasm :column => :status
17
- aasm do
18
- state :alpha, :initial => true
19
- state :beta
20
- state :gamma
21
- event :release do
22
- transitions :from => [:alpha, :beta, :gamma], :to => :beta
16
+ aasm :column => :status
17
+ aasm do
18
+ state :alpha, :initial => true
19
+ state :beta
20
+ state :gamma
21
+ event :release do
22
+ transitions :from => [:alpha, :beta, :gamma], :to => :beta
23
+ end
23
24
  end
24
25
  end
25
26
  end
@@ -0,0 +1,50 @@
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
+
3
+ [:silent_persistors, :multiple_silent_persistors].each do |t|
4
+ db.create_table(t) do
5
+ primary_key :id
6
+ String "name"
7
+ String "status"
8
+ end
9
+ end
10
+
11
+ module Sequel
12
+ class SilentPersistor < Sequel::Model(:silent_persistors)
13
+ plugin :validation_helpers
14
+
15
+ include AASM
16
+ aasm :column => :status, :whiny_persistence => false do
17
+ state :sleeping, :initial => true
18
+ state :running
19
+ event :run do
20
+ transitions :to => :running, :from => :sleeping
21
+ end
22
+ event :sleep do
23
+ transitions :to => :sleeping, :from => :running
24
+ end
25
+ end
26
+ def validate
27
+ validates_presence :name
28
+ end
29
+ end
30
+
31
+ class MultipleSilentPersistor< Sequel::Model(:multiple_silent_persistors)
32
+ plugin :validation_helpers
33
+
34
+ include AASM
35
+ aasm :left, :column => :status, :whiny_persistence => false do
36
+ state :sleeping, :initial => true
37
+ state :running
38
+ event :run do
39
+ transitions :to => :running, :from => :sleeping
40
+ end
41
+ event :sleep do
42
+ transitions :to => :sleeping, :from => :running
43
+ end
44
+ end
45
+
46
+ def validate
47
+ validates_presence :name
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,112 @@
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
+
3
+ [:transactors, :no_lock_transactors, :lock_transactors, :lock_no_wait_transactors, :multiple_transactors].each do |table_name|
4
+ db.create_table(table_name) do
5
+ primary_key :id
6
+ String "name"
7
+ String "status"
8
+ Fixnum "worker_id"
9
+ end
10
+ end
11
+
12
+ module Sequel
13
+ class Transactor < Sequel::Model(:transactors)
14
+
15
+ many_to_one :worker, class: 'Sequel::Worker'
16
+
17
+ include AASM
18
+ aasm :column => :status do
19
+ state :sleeping, :initial => true
20
+ state :running, :before_enter => :start_worker, :after_enter => :fail
21
+
22
+ event :run do
23
+ transitions :to => :running, :from => :sleeping
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def start_worker
30
+ worker.update(status: 'running')
31
+ end
32
+
33
+ def fail
34
+ raise StandardError.new('failed on purpose')
35
+ end
36
+
37
+ end
38
+
39
+ class NoLockTransactor < Sequel::Model(:no_lock_transactors)
40
+
41
+ many_to_one :worker, class: 'Sequel::Worker'
42
+
43
+ include AASM
44
+
45
+ aasm :column => :status do
46
+ state :sleeping, :initial => true
47
+ state :running
48
+
49
+ event :run do
50
+ transitions :to => :running, :from => :sleeping
51
+ end
52
+ end
53
+ end
54
+
55
+ class LockTransactor < Sequel::Model(:lock_transactors)
56
+
57
+ many_to_one :worker, class: 'Sequel::Worker'
58
+
59
+ include AASM
60
+
61
+ aasm :column => :status, requires_lock: true do
62
+ state :sleeping, :initial => true
63
+ state :running
64
+
65
+ event :run do
66
+ transitions :to => :running, :from => :sleeping
67
+ end
68
+ end
69
+ end
70
+
71
+ class LockNoWaitTransactor < Sequel::Model(:lock_no_wait_transactors)
72
+
73
+ many_to_one :worker, class: 'Sequel::Worker'
74
+
75
+ include AASM
76
+
77
+ aasm :column => :status, requires_lock: 'FOR UPDATE NOWAIT' do
78
+ state :sleeping, :initial => true
79
+ state :running
80
+
81
+ event :run do
82
+ transitions :to => :running, :from => :sleeping
83
+ end
84
+ end
85
+ end
86
+
87
+ class MultipleTransactor < Sequel::Model(:multiple_transactors)
88
+
89
+ many_to_one :worker, class: 'Sequel::Worker'
90
+
91
+ include AASM
92
+ aasm :left, :column => :status do
93
+ state :sleeping, :initial => true
94
+ state :running, :before_enter => :start_worker, :after_enter => :fail
95
+
96
+ event :run do
97
+ transitions :to => :running, :from => :sleeping
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def start_worker
104
+ worker.update(:status, 'running')
105
+ end
106
+
107
+ def fail
108
+ raise StandardError.new('failed on purpose')
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,93 @@
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
+
3
+ db.create_table(:validators) do
4
+ primary_key :id
5
+ String "name"
6
+ String "status"
7
+ Fixnum "worker_id"
8
+ end
9
+
10
+ module Sequel
11
+ class Validator < Sequel::Model(:validators)
12
+ plugin :validation_helpers
13
+
14
+ attr_accessor :after_all_transactions_performed,
15
+ :after_transaction_performed_on_fail,
16
+ :after_transaction_performed_on_run,
17
+ :before_all_transactions_performed,
18
+ :before_transaction_performed_on_fail,
19
+ :before_transaction_performed_on_run,
20
+ :invalid
21
+
22
+ def validate
23
+ super
24
+ errors.add(:validator, "invalid") if invalid
25
+ validates_presence :name
26
+ end
27
+
28
+ include AASM
29
+
30
+ aasm :column => :status, :whiny_persistence => true do
31
+ before_all_transactions :before_all_transactions
32
+ after_all_transactions :after_all_transactions
33
+
34
+ state :sleeping, :initial => true
35
+ state :running
36
+ state :failed, :after_enter => :fail
37
+
38
+ event :run, :after_commit => :change_name! do
39
+ after_transaction do
40
+ @after_transaction_performed_on_run = true
41
+ end
42
+
43
+ before_transaction do
44
+ @before_transaction_performed_on_run = true
45
+ end
46
+
47
+ transitions :to => :running, :from => :sleeping
48
+ end
49
+
50
+ event :sleep do
51
+ after_commit do |name|
52
+ change_name_on_sleep name
53
+ end
54
+ transitions :to => :sleeping, :from => :running
55
+ end
56
+
57
+ event :fail do
58
+ after_transaction do
59
+ @after_transaction_performed_on_fail = true
60
+ end
61
+
62
+ before_transaction do
63
+ @before_transaction_performed_on_fail = true
64
+ end
65
+
66
+ transitions :to => :failed, :from => [:sleeping, :running]
67
+ end
68
+ end
69
+
70
+ def change_name!
71
+ self.name = "name changed"
72
+ save(raise_on_failure: true)
73
+ end
74
+
75
+ def change_name_on_sleep name
76
+ self.name = name
77
+ save(raise_on_failure: true)
78
+ end
79
+
80
+ def fail
81
+ raise StandardError.new('failed on purpose')
82
+ end
83
+
84
+ def after_all_transactions
85
+ @after_all_transactions_performed = true
86
+ end
87
+
88
+ def before_all_transactions
89
+ @before_all_transactions_performed = true
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,12 @@
1
+ db = Sequel::DATABASES.first || Sequel.connect(SEQUEL_DB)
2
+
3
+ db.create_table(:workers) do
4
+ primary_key :id
5
+ String "name"
6
+ String "status"
7
+ end
8
+
9
+ module Sequel
10
+ class Worker < Sequel::Model(:workers)
11
+ end
12
+ end