aasm 5.0.2 → 5.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/Appraisals +17 -2
- data/CHANGELOG.md +18 -0
- data/README.md +93 -93
- data/gemfiles/norails.gemfile +10 -0
- data/gemfiles/rails_5.0.gemfile +1 -1
- data/gemfiles/rails_5.1.gemfile +1 -1
- data/gemfiles/rails_5.2.gemfile +13 -0
- data/lib/aasm/base.rb +6 -7
- data/lib/aasm/persistence/active_record_persistence.rb +2 -1
- data/lib/aasm/persistence/base.rb +1 -1
- data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
- data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
- data/lib/aasm/persistence/mongoid_persistence.rb +1 -1
- data/lib/aasm/persistence/no_brainer_persistence.rb +1 -1
- data/lib/aasm/persistence/redis_persistence.rb +1 -1
- data/lib/aasm/version.rb +1 -1
- data/spec/database.rb +3 -0
- data/spec/models/active_record/person.rb +23 -0
- data/spec/unit/abstract_class_spec.rb +27 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e702f783991a9de8f199c63ef2872f9929cde73
|
4
|
+
data.tar.gz: 9a1339c1f9e22d9bd7f00f6aabb493e303b1549e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b34c93b3e939d6803fb3f7987ba2510fb33be577ac786140474d36305441829ea4b8318ee034dea4a005ed365d4d4930d6d9f3d4847902fdb77a1e85d5210e7
|
7
|
+
data.tar.gz: 801b5dee037527de96cbf156eeebe6e92e216ce9bea97c9edf2bdd6e52790c66ff0e7186839afcb6d6a91ee3992028206f0b94089753380ba3d5701f68cb7312
|
data/.travis.yml
CHANGED
@@ -21,6 +21,7 @@ addons:
|
|
21
21
|
rethinkdb: '2.3.6'
|
22
22
|
|
23
23
|
gemfile:
|
24
|
+
- gemfiles/norails.gemfile
|
24
25
|
- gemfiles/rails_3.2.gemfile
|
25
26
|
- gemfiles/rails_4.2.gemfile
|
26
27
|
- gemfiles/rails_4.2_mongoid_5.gemfile
|
@@ -28,6 +29,7 @@ gemfile:
|
|
28
29
|
- gemfiles/rails_5.0.gemfile
|
29
30
|
- gemfiles/rails_5.0_nobrainer.gemfile
|
30
31
|
- gemfiles/rails_5.1.gemfile
|
32
|
+
- gemfiles/rails_5.2.gemfile
|
31
33
|
|
32
34
|
before_script:
|
33
35
|
- mkdir /tmp/dynamodb
|
@@ -41,12 +43,16 @@ script:
|
|
41
43
|
|
42
44
|
matrix:
|
43
45
|
exclude:
|
46
|
+
- rvm: 2.3.0
|
47
|
+
gemfile: gemfiles/norails.gemfile
|
44
48
|
- rvm: 2.3.0
|
45
49
|
gemfile: gemfiles/rails_5.0.gemfile
|
46
50
|
- rvm: 2.3.0
|
47
51
|
gemfile: gemfiles/rails_5.0_nobrainer.gemfile
|
48
52
|
- rvm: 2.3.0
|
49
53
|
gemfile: gemfiles/rails_5.1.gemfile
|
54
|
+
- rvm: 2.3.0
|
55
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
50
56
|
- rvm: 2.5.0
|
51
57
|
gemfile: gemfiles/rails_3.2.gemfile
|
52
58
|
- rvm: 2.5.0
|
@@ -55,10 +61,14 @@ matrix:
|
|
55
61
|
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
56
62
|
- rvm: 2.5.0
|
57
63
|
gemfile: gemfiles/rails_4.2_nobrainer.gemfile
|
64
|
+
- rvm: jruby-9.1.12.0
|
65
|
+
gemfile: gemfiles/norails.gemfile
|
58
66
|
- rvm: jruby-9.1.12.0
|
59
67
|
gemfile: gemfiles/rails_5.0.gemfile
|
60
68
|
- rvm: jruby-9.1.12.0
|
61
69
|
gemfile: gemfiles/rails_5.1.gemfile
|
70
|
+
- rvm: jruby-9.1.12.0
|
71
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
62
72
|
- rvm: jruby-9.1.12.0
|
63
73
|
gemfile: gemfiles/rails_4.2_nobrainer.gemfile
|
64
74
|
- rvm: jruby-9.1.12.0
|
data/Appraisals
CHANGED
@@ -36,7 +36,7 @@ appraise 'rails_5.0' do
|
|
36
36
|
gem 'rails', '5.0.0'
|
37
37
|
gem 'mongoid', '~> 6.0'
|
38
38
|
gem 'sequel'
|
39
|
-
gem 'dynamoid', '~> 1', platforms: :ruby
|
39
|
+
gem 'dynamoid', '~> 1.3', platforms: :ruby
|
40
40
|
gem 'aws-sdk', '~> 2', platforms: :ruby
|
41
41
|
gem 'redis-objects'
|
42
42
|
end
|
@@ -50,7 +50,22 @@ appraise 'rails_5.1' do
|
|
50
50
|
gem 'rails', '5.1'
|
51
51
|
gem 'mongoid', '~>6.0'
|
52
52
|
gem 'sequel'
|
53
|
-
gem 'dynamoid', '~> 1', platforms: :ruby
|
53
|
+
gem 'dynamoid', '~> 1.3', platforms: :ruby
|
54
|
+
gem 'aws-sdk', '~>2', platforms: :ruby
|
55
|
+
gem 'redis-objects'
|
56
|
+
end
|
57
|
+
|
58
|
+
appraise 'rails_5.2' do
|
59
|
+
gem 'rails', '5.2'
|
60
|
+
gem 'mongoid', '~>6.0'
|
61
|
+
gem 'sequel'
|
62
|
+
gem 'dynamoid', '~>2.2', platforms: :ruby
|
54
63
|
gem 'aws-sdk', '~>2', platforms: :ruby
|
55
64
|
gem 'redis-objects'
|
56
65
|
end
|
66
|
+
|
67
|
+
appraise 'norails' do
|
68
|
+
gem 'rails', install_if: false
|
69
|
+
gem 'sequel'
|
70
|
+
gem 'redis-objects'
|
71
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## 5.0.5
|
6
|
+
|
7
|
+
* Independent of ActiveSupport methods, [#627](https://github.com/aasm/aasm/pull/627),
|
8
|
+
thanks to [tristandruyen](https://github.com/tristandruyen). Fixes [#508](https://github.com/aasm/aasm/issues/508)
|
9
|
+
|
10
|
+
## 5.0.4
|
11
|
+
|
12
|
+
* Specify dynamoid version for Rails > 5, [#625](https://github.com/aasm/aasm/pull/625),
|
13
|
+
thanks to [waghanza](https://github.com/waghanza)
|
14
|
+
* Add travis runner for Rails 5.2, [#624](https://github.com/aasm/aasm/pull/624), thanks
|
15
|
+
to [waghanza](https://github.com/waghanza)
|
16
|
+
* Cleanup Abstract class issue, [#620](https://github.com/aasm/aasm/pull/620), thanks to
|
17
|
+
[dennym](https://github.com/dennym)
|
18
|
+
|
19
|
+
## 5.0.3
|
20
|
+
|
21
|
+
* Fix Abstract class issue, [#619](https://github.com/aasm/aasm/pull/619)
|
22
|
+
|
5
23
|
## 5.0.2
|
6
24
|
|
7
25
|
* Clear failed callbacks, [#600](https://github.com/aasm/aasm/pull/600), thanks to
|
data/README.md
CHANGED
@@ -70,19 +70,19 @@ class Job
|
|
70
70
|
include AASM
|
71
71
|
|
72
72
|
aasm do
|
73
|
-
state :sleeping, :
|
73
|
+
state :sleeping, initial: true
|
74
74
|
state :running, :cleaning
|
75
75
|
|
76
76
|
event :run do
|
77
|
-
transitions :
|
77
|
+
transitions from: :sleeping, to: :running
|
78
78
|
end
|
79
79
|
|
80
80
|
event :clean do
|
81
|
-
transitions :
|
81
|
+
transitions from: :running, to: :cleaning
|
82
82
|
end
|
83
83
|
|
84
84
|
event :sleep do
|
85
|
-
transitions :
|
85
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -108,7 +108,7 @@ AASM not to be *whiny*:
|
|
108
108
|
```ruby
|
109
109
|
class Job
|
110
110
|
...
|
111
|
-
aasm :
|
111
|
+
aasm whiny_transitions: false do
|
112
112
|
...
|
113
113
|
end
|
114
114
|
end
|
@@ -137,19 +137,19 @@ class Job
|
|
137
137
|
include AASM
|
138
138
|
|
139
139
|
aasm do
|
140
|
-
state :sleeping, :
|
140
|
+
state :sleeping, initial: true, before_enter: :do_something
|
141
141
|
state :running, before_enter: Proc.new { do_something && notify_somebody }
|
142
142
|
state :finished
|
143
143
|
|
144
144
|
after_all_transitions :log_status_change
|
145
145
|
|
146
|
-
event :run, :
|
146
|
+
event :run, after: :notify_somebody do
|
147
147
|
before do
|
148
148
|
log('Preparing to run')
|
149
149
|
end
|
150
150
|
|
151
|
-
transitions :
|
152
|
-
transitions :
|
151
|
+
transitions from: :sleeping, to: :running, after: Proc.new {|*args| set_process(*args) }
|
152
|
+
transitions from: :running, to: :finished, after: LogRunTime
|
153
153
|
end
|
154
154
|
|
155
155
|
event :sleep do
|
@@ -159,7 +159,7 @@ class Job
|
|
159
159
|
error do |e|
|
160
160
|
...
|
161
161
|
end
|
162
|
-
transitions :
|
162
|
+
transitions from: :running, to: :sleeping
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
@@ -219,7 +219,7 @@ Also, you can pass parameters to events:
|
|
219
219
|
|
220
220
|
In this case the `set_process` would be called with `:defragmentation` argument.
|
221
221
|
|
222
|
-
Note that when passing arguments to a state transition, the first argument
|
222
|
+
Note that when passing arguments to a state transition, the first argument should be the desired end state. In the above example, we wish to transition to `:running` state and run the callback with `:defragmentation` argument. You can also omit or pass in `nil` as the desired end state, and AASM will try to transition to the first end state defined for that event.
|
223
223
|
|
224
224
|
In case of an error during the event processing the error is rescued and passed to `:error`
|
225
225
|
callback, which can handle it or re-raise it for further propagation.
|
@@ -312,24 +312,24 @@ class Cleaner
|
|
312
312
|
include AASM
|
313
313
|
|
314
314
|
aasm do
|
315
|
-
state :idle, :
|
315
|
+
state :idle, initial: true
|
316
316
|
state :cleaning
|
317
317
|
|
318
318
|
event :clean do
|
319
|
-
transitions :
|
319
|
+
transitions from: :idle, to: :cleaning, guard: :cleaning_needed?
|
320
320
|
end
|
321
321
|
|
322
322
|
event :clean_if_needed do
|
323
|
-
transitions :
|
323
|
+
transitions from: :idle, to: :cleaning do
|
324
324
|
guard do
|
325
325
|
cleaning_needed?
|
326
326
|
end
|
327
327
|
end
|
328
|
-
transitions :
|
328
|
+
transitions from: :idle, to: :idle
|
329
329
|
end
|
330
330
|
|
331
331
|
event :clean_if_dirty do
|
332
|
-
transitions :
|
332
|
+
transitions from: :idle, to: :cleaning, guard: :if_dirty?
|
333
333
|
end
|
334
334
|
end
|
335
335
|
|
@@ -358,16 +358,16 @@ You can even provide a number of guards, which all have to succeed to proceed
|
|
358
358
|
def walked_the_dog?; ...; end
|
359
359
|
|
360
360
|
event :sleep do
|
361
|
-
transitions :
|
361
|
+
transitions from: :running, to: :sleeping, guards: [:cleaning_needed?, :walked_the_dog?]
|
362
362
|
end
|
363
363
|
```
|
364
364
|
|
365
365
|
If you want to provide guards for all transitions within an event, you can use event guards
|
366
366
|
|
367
367
|
```ruby
|
368
|
-
event :sleep, :
|
369
|
-
transitions :
|
370
|
-
transitions :
|
368
|
+
event :sleep, guards: [:walked_the_dog?] do
|
369
|
+
transitions from: :running, to: :sleeping, guards: [:cleaning_needed?]
|
370
|
+
transitions from: :cleaning, to: :sleeping
|
371
371
|
end
|
372
372
|
```
|
373
373
|
|
@@ -375,20 +375,20 @@ If you prefer a more Ruby-like guard syntax, you can use `if` and `unless` as we
|
|
375
375
|
|
376
376
|
```ruby
|
377
377
|
event :clean do
|
378
|
-
transitions :
|
378
|
+
transitions from: :running, to: :cleaning, if: :cleaning_needed?
|
379
379
|
end
|
380
380
|
|
381
381
|
event :sleep do
|
382
|
-
transitions :
|
382
|
+
transitions from: :running, to: :sleeping, unless: :cleaning_needed?
|
383
383
|
end
|
384
384
|
end
|
385
385
|
```
|
386
386
|
|
387
|
-
You can invoke a Class instead a method since this Class responds to `call`
|
387
|
+
You can invoke a Class instead a method since this Class responds to `call`
|
388
388
|
|
389
389
|
```ruby
|
390
390
|
event :sleep do
|
391
|
-
transitions :
|
391
|
+
transitions from: :running, to: :sleeping, guards: Dog
|
392
392
|
end
|
393
393
|
```
|
394
394
|
```ruby
|
@@ -411,7 +411,7 @@ class Job
|
|
411
411
|
include AASM
|
412
412
|
|
413
413
|
aasm do
|
414
|
-
state :stage1, :
|
414
|
+
state :stage1, initial: true
|
415
415
|
state :stage2
|
416
416
|
state :stage3
|
417
417
|
state :completed
|
@@ -442,30 +442,30 @@ built with one state machine per class in mind. Nonetheless, here's how to do it
|
|
442
442
|
class SimpleMultipleExample
|
443
443
|
include AASM
|
444
444
|
aasm(:move) do
|
445
|
-
state :standing, :
|
445
|
+
state :standing, initial: true
|
446
446
|
state :walking
|
447
447
|
state :running
|
448
448
|
|
449
449
|
event :walk do
|
450
|
-
transitions :
|
450
|
+
transitions from: :standing, to: :walking
|
451
451
|
end
|
452
452
|
event :run do
|
453
|
-
transitions :
|
453
|
+
transitions from: [:standing, :walking], to: :running
|
454
454
|
end
|
455
455
|
event :hold do
|
456
|
-
transitions :
|
456
|
+
transitions from: [:walking, :running], to: :standing
|
457
457
|
end
|
458
458
|
end
|
459
459
|
|
460
460
|
aasm(:work) do
|
461
|
-
state :sleeping, :
|
461
|
+
state :sleeping, initial: true
|
462
462
|
state :processing
|
463
463
|
|
464
464
|
event :start do
|
465
|
-
transitions :
|
465
|
+
transitions from: :sleeping, to: :processing
|
466
466
|
end
|
467
467
|
event :stop do
|
468
|
-
transitions :
|
468
|
+
transitions from: :processing, to: :sleeping
|
469
469
|
end
|
470
470
|
end
|
471
471
|
end
|
@@ -498,28 +498,28 @@ Alternatively, you can provide a namespace for each state machine:
|
|
498
498
|
class NamespacedMultipleExample
|
499
499
|
include AASM
|
500
500
|
aasm(:status) do
|
501
|
-
state :unapproved, :
|
501
|
+
state :unapproved, initial: true
|
502
502
|
state :approved
|
503
503
|
|
504
504
|
event :approve do
|
505
|
-
transitions :
|
505
|
+
transitions from: :unapproved, to: :approved
|
506
506
|
end
|
507
507
|
|
508
508
|
event :unapprove do
|
509
|
-
transitions :
|
509
|
+
transitions from: :approved, to: :unapproved
|
510
510
|
end
|
511
511
|
end
|
512
512
|
|
513
513
|
aasm(:review_status, namespace: :review) do
|
514
|
-
state :unapproved, :
|
514
|
+
state :unapproved, initial: true
|
515
515
|
state :approved
|
516
516
|
|
517
517
|
event :approve do
|
518
|
-
transitions :
|
518
|
+
transitions from: :unapproved, to: :approved
|
519
519
|
end
|
520
520
|
|
521
521
|
event :unapprove do
|
522
|
-
transitions :
|
522
|
+
transitions from: :approved, to: :unapproved
|
523
523
|
end
|
524
524
|
end
|
525
525
|
end
|
@@ -551,26 +551,26 @@ class Example
|
|
551
551
|
include AASM
|
552
552
|
|
553
553
|
aasm(:work) do
|
554
|
-
state :sleeping, :
|
554
|
+
state :sleeping, initial: true
|
555
555
|
state :processing
|
556
556
|
|
557
557
|
event :start do
|
558
|
-
transitions :
|
558
|
+
transitions from: :sleeping, to: :processing
|
559
559
|
end
|
560
560
|
event :stop do
|
561
|
-
transitions :
|
561
|
+
transitions from: :processing, to: :sleeping
|
562
562
|
end
|
563
563
|
end
|
564
564
|
|
565
565
|
aasm(:question) do
|
566
|
-
state :answered, :
|
566
|
+
state :answered, initial: true
|
567
567
|
state :asked
|
568
568
|
|
569
|
-
event :ask, :
|
570
|
-
transitions :
|
569
|
+
event :ask, binding_event: :start do
|
570
|
+
transitions from: :answered, to: :asked
|
571
571
|
end
|
572
|
-
event :answer, :
|
573
|
-
transitions :
|
572
|
+
event :answer, binding_event: :stop do
|
573
|
+
transitions from: :asked, to: :answered
|
574
574
|
end
|
575
575
|
end
|
576
576
|
end
|
@@ -616,7 +616,7 @@ class CustomAASMBase < AASM::Base
|
|
616
616
|
# A custom transiton that we want available across many AASM models.
|
617
617
|
def count_transitions!
|
618
618
|
klass.class_eval do
|
619
|
-
aasm :
|
619
|
+
aasm with_klass: CustomAASMBase do
|
620
620
|
after_all_transitions :increment_transition_count
|
621
621
|
end
|
622
622
|
end
|
@@ -653,19 +653,19 @@ class SimpleCustomExample
|
|
653
653
|
include AASM
|
654
654
|
|
655
655
|
# Let's build an AASM state machine with our custom class.
|
656
|
-
aasm :
|
656
|
+
aasm with_klass: CustomAASMBase do
|
657
657
|
requires_guards!
|
658
658
|
count_transitions!
|
659
659
|
|
660
|
-
state :initialised, :
|
660
|
+
state :initialised, initial: true
|
661
661
|
state :filled_out
|
662
662
|
state :authorised
|
663
663
|
|
664
664
|
event :fill_out do
|
665
|
-
transitions :
|
665
|
+
transitions from: :initialised, to: :filled_out, guard: :fillable?
|
666
666
|
end
|
667
667
|
event :authorise do
|
668
|
-
transitions :
|
668
|
+
transitions from: :filled_out, to: :authorised, guard: :authorizable?
|
669
669
|
end
|
670
670
|
end
|
671
671
|
end
|
@@ -682,15 +682,15 @@ class Job < ActiveRecord::Base
|
|
682
682
|
include AASM
|
683
683
|
|
684
684
|
aasm do # default column: aasm_state
|
685
|
-
state :sleeping, :
|
685
|
+
state :sleeping, initial: true
|
686
686
|
state :running
|
687
687
|
|
688
688
|
event :run do
|
689
|
-
transitions :
|
689
|
+
transitions from: :sleeping, to: :running
|
690
690
|
end
|
691
691
|
|
692
692
|
event :sleep do
|
693
|
-
transitions :
|
693
|
+
transitions from: :running, to: :sleeping
|
694
694
|
end
|
695
695
|
end
|
696
696
|
|
@@ -725,16 +725,16 @@ be updated in the database (just like ActiveRecord `update_column` is working).
|
|
725
725
|
class Job < ActiveRecord::Base
|
726
726
|
include AASM
|
727
727
|
|
728
|
-
aasm :
|
729
|
-
state :sleeping, :
|
728
|
+
aasm skip_validation_on_save: true do
|
729
|
+
state :sleeping, initial: true
|
730
730
|
state :running
|
731
731
|
|
732
732
|
event :run do
|
733
|
-
transitions :
|
733
|
+
transitions from: :sleeping, to: :running
|
734
734
|
end
|
735
735
|
|
736
736
|
event :sleep do
|
737
|
-
transitions :
|
737
|
+
transitions from: :running, to: :sleeping
|
738
738
|
end
|
739
739
|
end
|
740
740
|
|
@@ -748,12 +748,12 @@ configure _AASM_ to not allow direct assignment, like this:
|
|
748
748
|
class Job < ActiveRecord::Base
|
749
749
|
include AASM
|
750
750
|
|
751
|
-
aasm :
|
752
|
-
state :sleeping, :
|
751
|
+
aasm no_direct_assignment: true do
|
752
|
+
state :sleeping, initial: true
|
753
753
|
state :running
|
754
754
|
|
755
755
|
event :run do
|
756
|
-
transitions :
|
756
|
+
transitions from: :sleeping, to: :running
|
757
757
|
end
|
758
758
|
end
|
759
759
|
|
@@ -784,8 +784,8 @@ class Job < ActiveRecord::Base
|
|
784
784
|
running: 99
|
785
785
|
}
|
786
786
|
|
787
|
-
aasm :
|
788
|
-
state :sleeping, :
|
787
|
+
aasm column: :state, enum: true do
|
788
|
+
state :sleeping, initial: true
|
789
789
|
state :running
|
790
790
|
end
|
791
791
|
end
|
@@ -884,7 +884,7 @@ class Job < ActiveRecord::Base
|
|
884
884
|
include AASM
|
885
885
|
|
886
886
|
aasm do
|
887
|
-
state :sleeping, :
|
887
|
+
state :sleeping, initial: true
|
888
888
|
state :running
|
889
889
|
state :cleaning
|
890
890
|
end
|
@@ -913,8 +913,8 @@ defining the `AASM` states, like this:
|
|
913
913
|
class Job < ActiveRecord::Base
|
914
914
|
include AASM
|
915
915
|
|
916
|
-
aasm :
|
917
|
-
state :sleeping, :
|
916
|
+
aasm create_scopes: false do
|
917
|
+
state :sleeping, initial: true
|
918
918
|
state :running
|
919
919
|
state :cleaning
|
920
920
|
end
|
@@ -947,11 +947,11 @@ class Job < ActiveRecord::Base
|
|
947
947
|
include AASM
|
948
948
|
|
949
949
|
aasm do
|
950
|
-
state :sleeping, :
|
950
|
+
state :sleeping, initial: true
|
951
951
|
state :running
|
952
952
|
|
953
|
-
event :run, :
|
954
|
-
transitions :
|
953
|
+
event :run, after_commit: :notify_about_running_job do
|
954
|
+
transitions from: :sleeping, to: :running
|
955
955
|
end
|
956
956
|
end
|
957
957
|
|
@@ -977,14 +977,14 @@ If you want to encapsulate state changes within an own transaction, the behavior
|
|
977
977
|
of this nested transaction might be confusing. Take a look at
|
978
978
|
[ActiveRecord Nested Transactions](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)
|
979
979
|
if you want to know more about this. Nevertheless, AASM by default requires a new transaction
|
980
|
-
`transaction(:
|
980
|
+
`transaction(requires_new: true)`. You can override this behavior by changing
|
981
981
|
the configuration
|
982
982
|
|
983
983
|
```ruby
|
984
984
|
class Job < ActiveRecord::Base
|
985
985
|
include AASM
|
986
986
|
|
987
|
-
aasm :
|
987
|
+
aasm requires_new_transaction: false do
|
988
988
|
...
|
989
989
|
end
|
990
990
|
|
@@ -992,7 +992,7 @@ class Job < ActiveRecord::Base
|
|
992
992
|
end
|
993
993
|
```
|
994
994
|
|
995
|
-
which then leads to `transaction(:
|
995
|
+
which then leads to `transaction(requires_new: false)`, the Rails default.
|
996
996
|
|
997
997
|
Additionally, if you do not want any of your active record actions to be
|
998
998
|
wrapped in a transaction, you can specify the `use_transactions` flag. This can
|
@@ -1004,7 +1004,7 @@ result of a transaction or callback, even when some error occurs. The
|
|
1004
1004
|
class Job < ActiveRecord::Base
|
1005
1005
|
include AASM
|
1006
1006
|
|
1007
|
-
aasm :
|
1007
|
+
aasm use_transactions: false do
|
1008
1008
|
...
|
1009
1009
|
end
|
1010
1010
|
|
@@ -1027,7 +1027,7 @@ AASM supports [Active Record pessimistic locking via `with_lock`](http://api.rub
|
|
1027
1027
|
class Job < ActiveRecord::Base
|
1028
1028
|
include AASM
|
1029
1029
|
|
1030
|
-
aasm :
|
1030
|
+
aasm requires_lock: true do
|
1031
1031
|
...
|
1032
1032
|
end
|
1033
1033
|
|
@@ -1039,7 +1039,7 @@ end
|
|
1039
1039
|
class Job < ActiveRecord::Base
|
1040
1040
|
include AASM
|
1041
1041
|
|
1042
|
-
aasm :
|
1042
|
+
aasm requires_lock: 'FOR UPDATE NOWAIT' do
|
1043
1043
|
...
|
1044
1044
|
end
|
1045
1045
|
|
@@ -1057,7 +1057,7 @@ this by defining your favorite column name, using `:column` like this:
|
|
1057
1057
|
class Job < ActiveRecord::Base
|
1058
1058
|
include AASM
|
1059
1059
|
|
1060
|
-
aasm :
|
1060
|
+
aasm column: 'my_state' do
|
1061
1061
|
...
|
1062
1062
|
end
|
1063
1063
|
|
@@ -1093,19 +1093,19 @@ class Job
|
|
1093
1093
|
include AASM
|
1094
1094
|
|
1095
1095
|
aasm do
|
1096
|
-
state :sleeping, :
|
1096
|
+
state :sleeping, initial: true
|
1097
1097
|
state :running, :cleaning
|
1098
1098
|
|
1099
1099
|
event :run do
|
1100
|
-
transitions :
|
1100
|
+
transitions from: :sleeping, to: :running
|
1101
1101
|
end
|
1102
1102
|
|
1103
1103
|
event :clean do
|
1104
|
-
transitions :
|
1104
|
+
transitions from: :running, to: :cleaning, guard: :cleaning_needed?
|
1105
1105
|
end
|
1106
1106
|
|
1107
1107
|
event :sleep do
|
1108
|
-
transitions :
|
1108
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
1109
1109
|
end
|
1110
1110
|
end
|
1111
1111
|
|
@@ -1123,15 +1123,15 @@ Job.aasm.states.map(&:name)
|
|
1123
1123
|
job = Job.new
|
1124
1124
|
|
1125
1125
|
# show all permitted states (from initial state)
|
1126
|
-
job.aasm.states(:
|
1126
|
+
job.aasm.states(permitted: true).map(&:name)
|
1127
1127
|
#=> [:running]
|
1128
1128
|
|
1129
1129
|
job.run
|
1130
|
-
job.aasm.states(:
|
1130
|
+
job.aasm.states(permitted: true).map(&:name)
|
1131
1131
|
#=> [:sleeping]
|
1132
1132
|
|
1133
1133
|
# show all non permitted states
|
1134
|
-
job.aasm.states(:
|
1134
|
+
job.aasm.states(permitted: false).map(&:name)
|
1135
1135
|
#=> [:cleaning]
|
1136
1136
|
|
1137
1137
|
# show all possible (triggerable) events from the current state
|
@@ -1139,23 +1139,23 @@ job.aasm.events.map(&:name)
|
|
1139
1139
|
#=> [:clean, :sleep]
|
1140
1140
|
|
1141
1141
|
# show all permitted events
|
1142
|
-
job.aasm.events(:
|
1142
|
+
job.aasm.events(permitted: true).map(&:name)
|
1143
1143
|
#=> [:sleep]
|
1144
1144
|
|
1145
1145
|
# show all non permitted events
|
1146
|
-
job.aasm.events(:
|
1146
|
+
job.aasm.events(permitted: false).map(&:name)
|
1147
1147
|
#=> [:clean]
|
1148
1148
|
|
1149
1149
|
# show all possible events except a specific one
|
1150
|
-
job.aasm.events(:
|
1150
|
+
job.aasm.events(reject: :sleep).map(&:name)
|
1151
1151
|
#=> [:clean]
|
1152
1152
|
|
1153
1153
|
# list states for select
|
1154
1154
|
Job.aasm.states_for_select
|
1155
|
-
|
1155
|
+
#=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
|
1156
1156
|
|
1157
1157
|
# show permitted states with guard parameter
|
1158
|
-
job.aasm.states({:
|
1158
|
+
job.aasm.states({permitted: true}, guard_parameter).map(&:name)
|
1159
1159
|
```
|
1160
1160
|
|
1161
1161
|
|
@@ -1168,7 +1168,7 @@ use
|
|
1168
1168
|
class Job
|
1169
1169
|
include AASM
|
1170
1170
|
|
1171
|
-
aasm :
|
1171
|
+
aasm logger: Rails.logger do
|
1172
1172
|
...
|
1173
1173
|
end
|
1174
1174
|
end
|
@@ -1192,12 +1192,12 @@ the 'instance method symbol / string' way whenever possible when defining guardi
|
|
1192
1192
|
|
1193
1193
|
#### RSpec
|
1194
1194
|
|
1195
|
-
AASM provides some matchers for [RSpec](http://rspec.info):
|
1196
|
-
*`transition_from`,
|
1195
|
+
AASM provides some matchers for [RSpec](http://rspec.info):
|
1196
|
+
*`transition_from`,
|
1197
1197
|
* `have_state`, `allow_event`
|
1198
|
-
* and `allow_transition_to`.
|
1198
|
+
* and `allow_transition_to`.
|
1199
1199
|
|
1200
|
-
##### Installation Instructions:
|
1200
|
+
##### Installation Instructions:
|
1201
1201
|
* Add `require 'aasm/rspec'` to your `spec_helper.rb` file.
|
1202
1202
|
|
1203
1203
|
##### Examples Of Usage in Rspec:
|
data/gemfiles/rails_5.0.gemfile
CHANGED
data/gemfiles/rails_5.1.gemfile
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "sqlite3", "~> 1.3.5", platforms: :ruby
|
6
|
+
gem "rails", "5.2"
|
7
|
+
gem "mongoid", "~>6.0"
|
8
|
+
gem "sequel"
|
9
|
+
gem "dynamoid", "~>2.2", platforms: :ruby
|
10
|
+
gem "aws-sdk", "~>2", platforms: :ruby
|
11
|
+
gem "redis-objects"
|
12
|
+
|
13
|
+
gemspec path: "../"
|
data/lib/aasm/base.rb
CHANGED
@@ -54,13 +54,12 @@ module AASM
|
|
54
54
|
# make sure to raise an error if no_direct_assignment is enabled
|
55
55
|
# and attribute is directly assigned though
|
56
56
|
aasm_name = @name
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
super(state_name)
|
57
|
+
|
58
|
+
if @state_machine.config.no_direct_assignment
|
59
|
+
@klass.send(:define_method, "#{@state_machine.config.column}=") do |state_name|
|
60
|
+
if self.class.aasm(:"#{aasm_name}").state_machine.config.no_direct_assignment
|
61
|
+
raise AASM::NoDirectAssignmentError.new('direct assignment of AASM column has been disabled (see AASM configuration for this class)')
|
62
|
+
end
|
64
63
|
end
|
65
64
|
end
|
66
65
|
end
|
@@ -141,7 +141,8 @@ module AASM
|
|
141
141
|
|
142
142
|
def aasm_column_is_blank?(state_machine_name)
|
143
143
|
attribute_name = self.class.aasm(state_machine_name).attribute_name
|
144
|
-
attribute_names.include?(attribute_name.to_s) &&
|
144
|
+
attribute_names.include?(attribute_name.to_s) &&
|
145
|
+
(send(attribute_name).respond_to?(:empty?) ? !!send(attribute_name).empty? : !send(attribute_name))
|
145
146
|
end
|
146
147
|
|
147
148
|
def aasm_validate_states
|
@@ -34,7 +34,7 @@ module AASM
|
|
34
34
|
# This allows for nil aasm states - be sure to add validation to your model
|
35
35
|
def aasm_read_state(name=:default)
|
36
36
|
state = send(self.class.aasm(name).attribute_name)
|
37
|
-
if state.
|
37
|
+
if !state || state.empty?
|
38
38
|
aasm_new_record? ? aasm(name).determine_state_name(self.class.aasm(name).initial_state) : nil
|
39
39
|
else
|
40
40
|
state.to_sym
|
@@ -77,7 +77,8 @@ module AASM
|
|
77
77
|
#
|
78
78
|
def aasm_ensure_initial_state
|
79
79
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
|
80
|
-
send(
|
80
|
+
next if !send(self.class.aasm(state_machine_name).attribute_name) || send(self.class.aasm(state_machine_name).attribute_name).empty?
|
81
|
+
send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s)
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end # InstanceMethods
|
@@ -83,7 +83,7 @@ module AASM
|
|
83
83
|
#
|
84
84
|
def aasm_ensure_initial_state
|
85
85
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
|
86
|
-
aasm(state_machine_name).enter_initial_state if send(self.class.aasm(state_machine_name).attribute_name).
|
86
|
+
aasm(state_machine_name).enter_initial_state if !send(self.class.aasm(state_machine_name).attribute_name) || send(self.class.aasm(state_machine_name).attribute_name).empty?
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end # InstanceMethods
|
@@ -106,7 +106,7 @@ module AASM
|
|
106
106
|
# mongoid has_many relationship does not load child object attributes when
|
107
107
|
# only ids are loaded, for example parent.child_ids will not load child object attributes.
|
108
108
|
# This feature is introduced in mongoid > 4.
|
109
|
-
if attribute_names.include?(attribute_name) && attributes[attribute_name].
|
109
|
+
if attribute_names.include?(attribute_name) && !attributes[attribute_name] || attributes[attribute_name].empty?
|
110
110
|
# attribute_missing? is defined in mongoid > 4
|
111
111
|
return if Mongoid::VERSION.to_f >= 4 && attribute_missing?(attribute_name)
|
112
112
|
send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s)
|
@@ -96,7 +96,7 @@ module AASM
|
|
96
96
|
def aasm_ensure_initial_state
|
97
97
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |name|
|
98
98
|
aasm_column = self.class.aasm(name).attribute_name
|
99
|
-
aasm(name).enter_initial_state if read_attribute(aasm_column).
|
99
|
+
aasm(name).enter_initial_state if !read_attribute(aasm_column) || read_attribute(aasm_column).empty?
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end # InstanceMethods
|
@@ -69,7 +69,7 @@ module AASM
|
|
69
69
|
def aasm_ensure_initial_state
|
70
70
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |name|
|
71
71
|
aasm_column = self.class.aasm(name).attribute_name
|
72
|
-
aasm(name).enter_initial_state if send(aasm_column).value.
|
72
|
+
aasm(name).enter_initial_state if !send(aasm_column).value || send(aasm_column).value.empty?
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
data/lib/aasm/version.rb
CHANGED
data/spec/database.rb
CHANGED
@@ -14,6 +14,9 @@ ActiveRecord::Migration.suppress_messages do
|
|
14
14
|
ActiveRecord::Migration.create_table "implemented_abstract_class_dsls", :force => true do |t|
|
15
15
|
t.string "status"
|
16
16
|
end
|
17
|
+
ActiveRecord::Migration.create_table "users", :force => true do |t|
|
18
|
+
t.string "status"
|
19
|
+
end
|
17
20
|
|
18
21
|
ActiveRecord::Migration.create_table "complex_active_record_examples", :force => true do |t|
|
19
22
|
t.string "left"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Base < ActiveRecord::Base
|
2
|
+
include AASM
|
3
|
+
|
4
|
+
aasm column: 'status' do
|
5
|
+
state :inactive, initial: true
|
6
|
+
state :active
|
7
|
+
|
8
|
+
event :activate do
|
9
|
+
transitions from: :inactive, to: :active
|
10
|
+
end
|
11
|
+
|
12
|
+
event :deactivate do
|
13
|
+
transitions from: :active, to: :inactive
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
self.abstract_class = true
|
18
|
+
self.table_name = 'users'
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class Person < Base
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
if defined?(ActiveRecord)
|
3
|
+
require 'models/active_record/person'
|
4
|
+
|
5
|
+
load_schema
|
6
|
+
describe 'Abstract subclassing' do
|
7
|
+
|
8
|
+
it 'should have the parent states' do
|
9
|
+
Person.aasm.states.each do |state|
|
10
|
+
expect(Base.aasm.states).to include(state)
|
11
|
+
end
|
12
|
+
expect(Person.aasm.states).to eq(Base.aasm.states)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have the same events as its parent' do
|
16
|
+
expect(Base.aasm.events).to eq(Person.aasm.events)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should not break aasm methods when super class is abstract_class' do
|
20
|
+
person = Person.new
|
21
|
+
person.status = 'active'
|
22
|
+
person.deactivate!
|
23
|
+
expect(person.aasm.current_state).to eq(:inactive)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thorsten Boettger
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-05-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: concurrent-ruby
|
@@ -137,6 +137,7 @@ files:
|
|
137
137
|
- aasm.gemspec
|
138
138
|
- callbacks.txt
|
139
139
|
- docker-compose.yml
|
140
|
+
- gemfiles/norails.gemfile
|
140
141
|
- gemfiles/rails_3.2.gemfile
|
141
142
|
- gemfiles/rails_4.2.gemfile
|
142
143
|
- gemfiles/rails_4.2_mongoid_5.gemfile
|
@@ -144,6 +145,7 @@ files:
|
|
144
145
|
- gemfiles/rails_5.0.gemfile
|
145
146
|
- gemfiles/rails_5.0_nobrainer.gemfile
|
146
147
|
- gemfiles/rails_5.1.gemfile
|
148
|
+
- gemfiles/rails_5.2.gemfile
|
147
149
|
- lib/aasm.rb
|
148
150
|
- lib/aasm/aasm.rb
|
149
151
|
- lib/aasm/base.rb
|
@@ -210,6 +212,7 @@ files:
|
|
210
212
|
- spec/models/active_record/no_direct_assignment.rb
|
211
213
|
- spec/models/active_record/no_scope.rb
|
212
214
|
- spec/models/active_record/persisted_state.rb
|
215
|
+
- spec/models/active_record/person.rb
|
213
216
|
- spec/models/active_record/provided_and_persisted_state.rb
|
214
217
|
- spec/models/active_record/reader.rb
|
215
218
|
- spec/models/active_record/readme_job.rb
|
@@ -312,6 +315,7 @@ files:
|
|
312
315
|
- spec/spec_helpers/redis.rb
|
313
316
|
- spec/spec_helpers/remove_warnings.rb
|
314
317
|
- spec/spec_helpers/sequel.rb
|
318
|
+
- spec/unit/abstract_class_spec.rb
|
315
319
|
- spec/unit/api_spec.rb
|
316
320
|
- spec/unit/basic_two_state_machines_example_spec.rb
|
317
321
|
- spec/unit/callback_multiple_spec.rb
|
@@ -411,6 +415,7 @@ test_files:
|
|
411
415
|
- spec/models/active_record/no_direct_assignment.rb
|
412
416
|
- spec/models/active_record/no_scope.rb
|
413
417
|
- spec/models/active_record/persisted_state.rb
|
418
|
+
- spec/models/active_record/person.rb
|
414
419
|
- spec/models/active_record/provided_and_persisted_state.rb
|
415
420
|
- spec/models/active_record/reader.rb
|
416
421
|
- spec/models/active_record/readme_job.rb
|
@@ -513,6 +518,7 @@ test_files:
|
|
513
518
|
- spec/spec_helpers/redis.rb
|
514
519
|
- spec/spec_helpers/remove_warnings.rb
|
515
520
|
- spec/spec_helpers/sequel.rb
|
521
|
+
- spec/unit/abstract_class_spec.rb
|
516
522
|
- spec/unit/api_spec.rb
|
517
523
|
- spec/unit/basic_two_state_machines_example_spec.rb
|
518
524
|
- spec/unit/callback_multiple_spec.rb
|