aasm 5.0.2 → 5.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.travis.yml +42 -11
- data/Appraisals +17 -2
- data/CHANGELOG.md +33 -0
- data/Dockerfile +1 -6
- data/README.md +118 -99
- data/aasm.gemspec +3 -0
- 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/aasm.rb +29 -27
- data/lib/aasm/base.rb +25 -7
- data/lib/aasm/core/event.rb +3 -3
- data/lib/aasm/instance_base.rb +15 -3
- data/lib/aasm/persistence/active_record_persistence.rb +10 -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/orm.rb +23 -19
- data/lib/aasm/persistence/redis_persistence.rb +1 -1
- data/lib/aasm/rspec/transition_from.rb +5 -1
- data/lib/aasm/version.rb +1 -1
- data/spec/database.rb +8 -0
- data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
- data/spec/models/active_record/person.rb +23 -0
- data/spec/models/callbacks/with_state_arg.rb +5 -1
- data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
- data/spec/models/simple_example.rb +6 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/abstract_class_spec.rb +27 -0
- data/spec/unit/callback_multiple_spec.rb +4 -0
- data/spec/unit/callbacks_spec.rb +4 -0
- data/spec/unit/complex_example_spec.rb +0 -1
- data/spec/unit/event_spec.rb +13 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +4 -4
- data/spec/unit/persistence/active_record_persistence_spec.rb +58 -4
- data/spec/unit/rspec_matcher_spec.rb +3 -0
- data/spec/unit/simple_example_spec.rb +15 -0
- metadata +54 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa5a74637dafaa4c06da6c03e96342997692ad3f
|
4
|
+
data.tar.gz: e46be5420174440acc2dea63d9e66958d7dc6efc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 359caf35d39d769ec0cc3d805cface2f89946692e62b1dd984fc42830be53305c3abfb300163d6e2f46317673fbd3a1c9e8ea366328feebdedab5806b85f1fd0
|
7
|
+
data.tar.gz: a1621683151f4ff00e1e83f4d7f3926bc1d5d4e0d945e2a38ed4f6355267c0165e2aabbeca553cdf17a8c9e4237130a0a63cc9715b0b0e8bb5801c71bd2bb053
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Create a report to help us improve
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Describe the bug**
|
11
|
+
A clear and concise description of what the bug is.
|
12
|
+
|
13
|
+
**To Reproduce**
|
14
|
+
Steps to reproduce the behavior:
|
15
|
+
1. Go to '...'
|
16
|
+
2. Click on '....'
|
17
|
+
3. Scroll down to '....'
|
18
|
+
4. See error
|
19
|
+
|
20
|
+
**Expected behavior**
|
21
|
+
A clear and concise description of what you expected to happen.
|
22
|
+
|
23
|
+
**Screenshots**
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
25
|
+
|
26
|
+
**Additional context**
|
27
|
+
Add any other context about the problem here.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
12
|
+
|
13
|
+
**Describe the solution you'd like**
|
14
|
+
A clear and concise description of what you want to happen.
|
15
|
+
|
16
|
+
**Describe alternatives you've considered**
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
18
|
+
|
19
|
+
**Additional context**
|
20
|
+
Add any other context or screenshots about the feature request here.
|
data/.travis.yml
CHANGED
@@ -2,6 +2,9 @@ sudo: false
|
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
4
|
|
5
|
+
jdk:
|
6
|
+
- openjdk8
|
7
|
+
|
5
8
|
before_install:
|
6
9
|
- rvm list
|
7
10
|
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
@@ -11,23 +14,27 @@ before_install:
|
|
11
14
|
rvm:
|
12
15
|
- 2.3.0
|
13
16
|
- 2.5.0
|
17
|
+
- 2.6.5
|
18
|
+
- 2.7.0
|
14
19
|
- jruby-9.1.12.0
|
15
20
|
|
16
21
|
services:
|
17
22
|
- mongodb
|
18
23
|
- redis-server
|
19
24
|
|
20
|
-
addons:
|
21
|
-
rethinkdb: '2.3.
|
25
|
+
#addons:
|
26
|
+
# rethinkdb: '2.3.4'
|
22
27
|
|
23
28
|
gemfile:
|
29
|
+
- gemfiles/norails.gemfile
|
24
30
|
- gemfiles/rails_3.2.gemfile
|
25
31
|
- gemfiles/rails_4.2.gemfile
|
26
32
|
- gemfiles/rails_4.2_mongoid_5.gemfile
|
27
|
-
- gemfiles/rails_4.2_nobrainer.gemfile
|
33
|
+
# - gemfiles/rails_4.2_nobrainer.gemfile
|
28
34
|
- gemfiles/rails_5.0.gemfile
|
29
|
-
- gemfiles/rails_5.0_nobrainer.gemfile
|
35
|
+
# - gemfiles/rails_5.0_nobrainer.gemfile
|
30
36
|
- gemfiles/rails_5.1.gemfile
|
37
|
+
- gemfiles/rails_5.2.gemfile
|
31
38
|
|
32
39
|
before_script:
|
33
40
|
- mkdir /tmp/dynamodb
|
@@ -42,27 +49,51 @@ script:
|
|
42
49
|
matrix:
|
43
50
|
exclude:
|
44
51
|
- rvm: 2.3.0
|
45
|
-
gemfile: gemfiles/
|
52
|
+
gemfile: gemfiles/norails.gemfile
|
46
53
|
- rvm: 2.3.0
|
47
|
-
gemfile: gemfiles/rails_5.
|
54
|
+
gemfile: gemfiles/rails_5.0.gemfile
|
55
|
+
# - rvm: 2.3.0
|
56
|
+
# gemfile: gemfiles/rails_5.0_nobrainer.gemfile
|
48
57
|
- rvm: 2.3.0
|
49
58
|
gemfile: gemfiles/rails_5.1.gemfile
|
59
|
+
- rvm: 2.3.0
|
60
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
61
|
+
- rvm: 2.7.0
|
62
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
63
|
+
- rvm: 2.6.5
|
64
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
50
65
|
- rvm: 2.5.0
|
51
66
|
gemfile: gemfiles/rails_3.2.gemfile
|
67
|
+
- rvm: 2.6.5
|
68
|
+
gemfile: gemfiles/rails_3.2.gemfile
|
69
|
+
- rvm: 2.7.0
|
70
|
+
gemfile: gemfiles/rails_3.2.gemfile
|
52
71
|
- rvm: 2.5.0
|
53
72
|
gemfile: gemfiles/rails_4.2.gemfile
|
73
|
+
- rvm: 2.6.5
|
74
|
+
gemfile: gemfiles/rails_4.2.gemfile
|
75
|
+
- rvm: 2.7.0
|
76
|
+
gemfile: gemfiles/rails_4.2.gemfile
|
54
77
|
- rvm: 2.5.0
|
55
78
|
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
56
|
-
- rvm: 2.5
|
57
|
-
gemfile: gemfiles/rails_4.
|
79
|
+
- rvm: 2.6.5
|
80
|
+
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
81
|
+
- rvm: 2.7.0
|
82
|
+
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
83
|
+
# - rvm: 2.5.0
|
84
|
+
# gemfile: gemfiles/rails_4.2_nobrainer.gemfile
|
85
|
+
- rvm: jruby-9.1.12.0
|
86
|
+
gemfile: gemfiles/norails.gemfile
|
58
87
|
- rvm: jruby-9.1.12.0
|
59
88
|
gemfile: gemfiles/rails_5.0.gemfile
|
60
89
|
- rvm: jruby-9.1.12.0
|
61
90
|
gemfile: gemfiles/rails_5.1.gemfile
|
62
91
|
- rvm: jruby-9.1.12.0
|
63
|
-
gemfile: gemfiles/
|
64
|
-
- rvm: jruby-9.1.12.0
|
65
|
-
gemfile: gemfiles/
|
92
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
93
|
+
# - rvm: jruby-9.1.12.0
|
94
|
+
# gemfile: gemfiles/rails_4.2_nobrainer.gemfile
|
95
|
+
# - rvm: jruby-9.1.12.0
|
96
|
+
# gemfile: gemfiles/rails_5.0_nobrainer.gemfile
|
66
97
|
|
67
98
|
notifications:
|
68
99
|
slack:
|
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,39 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## 5.0.7
|
6
|
+
|
7
|
+
* Fix :after_commit within nested transaction [#666](https://github.com/aasm/aasm/pull/666), thanks to [stokarenko](https://github.com/stokarenko)
|
8
|
+
* Add permitted_transitions to group permitted event with state [#664](https://github.com/aasm/aasm/pull/664), thanks to [dnamsons](https://github.com/dnamsons)
|
9
|
+
* Add Ruby 2.7.0 & 2.6.5 to Travis CI Test Matrix [#661](https://github.com/aasm/aasm/pull/661), thanks to [the-spectator](https://github.com/the-spectator)
|
10
|
+
* Handle InvalidTransition in transition_from matcher [#653](https://github.com/aasm/aasm/pull/653), thanks to [ryanwood](https://github.com/ryanwood)
|
11
|
+
|
12
|
+
## 5.0.6
|
13
|
+
|
14
|
+
* Fix no_direct_assignment, couldn't be turned off pragmatically [#636](https://github.com/aasm/aasm/issues/636)
|
15
|
+
* Add instance level validation skip option [#644](https://github.com/aasm/aasm/pull/644), thanks to [Nitin-Salunke](https://github.com/Nitin-Salunke)
|
16
|
+
* Fixed aasm.current_event incorrectly yields nil when calling aasm.fire!(:event) [#551](https://github.com/aasm/aasm/issues/551) in [#638](https://github.com/aasm/aasm/pull/638), thanks to [DoubleJarvis](https://github.com/DoubleJarvis)
|
17
|
+
* Code Refactor [#634](https://github.com/aasm/aasm/pull/634) , thanks to [rahulknojha](https://github.com/rahulknojha)
|
18
|
+
* Fixed callback argument for :before_success & :success callback, [#630](https://github.com/aasm/aasm/pull/630)
|
19
|
+
|
20
|
+
## 5.0.5
|
21
|
+
|
22
|
+
* Independent of ActiveSupport methods, [#627](https://github.com/aasm/aasm/pull/627),
|
23
|
+
thanks to [tristandruyen](https://github.com/tristandruyen). Fixes [#508](https://github.com/aasm/aasm/issues/508)
|
24
|
+
|
25
|
+
## 5.0.4
|
26
|
+
|
27
|
+
* Specify dynamoid version for Rails > 5, [#625](https://github.com/aasm/aasm/pull/625),
|
28
|
+
thanks to [waghanza](https://github.com/waghanza)
|
29
|
+
* Add travis runner for Rails 5.2, [#624](https://github.com/aasm/aasm/pull/624), thanks
|
30
|
+
to [waghanza](https://github.com/waghanza)
|
31
|
+
* Cleanup Abstract class issue, [#620](https://github.com/aasm/aasm/pull/620), thanks to
|
32
|
+
[dennym](https://github.com/dennym)
|
33
|
+
|
34
|
+
## 5.0.3
|
35
|
+
|
36
|
+
* Fix Abstract class issue, [#619](https://github.com/aasm/aasm/pull/619)
|
37
|
+
|
5
38
|
## 5.0.2
|
6
39
|
|
7
40
|
* Clear failed callbacks, [#600](https://github.com/aasm/aasm/pull/600), thanks to
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[](http://badge.fury.io/rb/aasm)
|
4
4
|
[](https://travis-ci.org/aasm/aasm)
|
5
5
|
[](https://codeclimate.com/github/aasm/aasm)
|
6
|
+
[](https://codecov.io/gh/aasm/aasm)
|
6
7
|
|
7
8
|
## Index
|
8
9
|
- [Upgrade from version 3 to 4](#upgrade-from-version-3-to-4)
|
@@ -29,6 +30,7 @@
|
|
29
30
|
- [Transaction support](#transaction-support)
|
30
31
|
- [Pessimistic Locking](#pessimistic-locking)
|
31
32
|
- [Column name & migration](#column-name--migration)
|
33
|
+
- [Log State Changes](#log-state-changes)
|
32
34
|
- [Inspection](#inspection)
|
33
35
|
- [Warning output](#warning-output)
|
34
36
|
- [RubyMotion support](#rubymotion-support)
|
@@ -70,19 +72,19 @@ class Job
|
|
70
72
|
include AASM
|
71
73
|
|
72
74
|
aasm do
|
73
|
-
state :sleeping, :
|
75
|
+
state :sleeping, initial: true
|
74
76
|
state :running, :cleaning
|
75
77
|
|
76
78
|
event :run do
|
77
|
-
transitions :
|
79
|
+
transitions from: :sleeping, to: :running
|
78
80
|
end
|
79
81
|
|
80
82
|
event :clean do
|
81
|
-
transitions :
|
83
|
+
transitions from: :running, to: :cleaning
|
82
84
|
end
|
83
85
|
|
84
86
|
event :sleep do
|
85
|
-
transitions :
|
87
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
@@ -108,7 +110,7 @@ AASM not to be *whiny*:
|
|
108
110
|
```ruby
|
109
111
|
class Job
|
110
112
|
...
|
111
|
-
aasm :
|
113
|
+
aasm whiny_transitions: false do
|
112
114
|
...
|
113
115
|
end
|
114
116
|
end
|
@@ -137,19 +139,19 @@ class Job
|
|
137
139
|
include AASM
|
138
140
|
|
139
141
|
aasm do
|
140
|
-
state :sleeping, :
|
142
|
+
state :sleeping, initial: true, before_enter: :do_something
|
141
143
|
state :running, before_enter: Proc.new { do_something && notify_somebody }
|
142
144
|
state :finished
|
143
145
|
|
144
146
|
after_all_transitions :log_status_change
|
145
147
|
|
146
|
-
event :run, :
|
148
|
+
event :run, after: :notify_somebody do
|
147
149
|
before do
|
148
150
|
log('Preparing to run')
|
149
151
|
end
|
150
152
|
|
151
|
-
transitions :
|
152
|
-
transitions :
|
153
|
+
transitions from: :sleeping, to: :running, after: Proc.new {|*args| set_process(*args) }
|
154
|
+
transitions from: :running, to: :finished, after: LogRunTime
|
153
155
|
end
|
154
156
|
|
155
157
|
event :sleep do
|
@@ -159,7 +161,7 @@ class Job
|
|
159
161
|
error do |e|
|
160
162
|
...
|
161
163
|
end
|
162
|
-
transitions :
|
164
|
+
transitions from: :running, to: :sleeping
|
163
165
|
end
|
164
166
|
end
|
165
167
|
|
@@ -214,13 +216,11 @@ Also, you can pass parameters to events:
|
|
214
216
|
|
215
217
|
```ruby
|
216
218
|
job = Job.new
|
217
|
-
job.run(:
|
219
|
+
job.run(:defragmentation)
|
218
220
|
```
|
219
221
|
|
220
222
|
In this case the `set_process` would be called with `:defragmentation` argument.
|
221
223
|
|
222
|
-
Note that when passing arguments to a state transition, the first argument must 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 pass in `nil` as the desired end state, and AASM will try to transition to the first end state defined for that event.
|
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.
|
226
226
|
|
@@ -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
|
@@ -436,36 +436,36 @@ job.aasm.current_state # stage3
|
|
436
436
|
### Multiple state machines per class
|
437
437
|
|
438
438
|
Multiple state machines per class are supported. Be aware though that _AASM_ has been
|
439
|
-
built with one state machine per class in mind. Nonetheless, here's how to do it
|
439
|
+
built with one state machine per class in mind. Nonetheless, here's how to do it (see below). Please note that you will need to specify database columns for where your pertinent states will be stored - we have specified two columns `move_state` and `work_state` in the example below. See the [Column name & migration](https://github.com/aasm/aasm#column-name--migration) section for further info.
|
440
440
|
|
441
441
|
```ruby
|
442
442
|
class SimpleMultipleExample
|
443
443
|
include AASM
|
444
|
-
aasm(:move) do
|
445
|
-
state :standing, :
|
444
|
+
aasm(:move, column: 'move_state') do
|
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
|
-
aasm(:work) do
|
461
|
-
state :sleeping, :
|
460
|
+
aasm(:work, column: 'work_state') do
|
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,22 +725,30 @@ 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
|
|
741
741
|
end
|
742
742
|
```
|
743
743
|
|
744
|
+
Also You can skip the validation at instance level with `some_event_name_without_validation!` method.
|
745
|
+
With this you have the flexibility of having validation for all your transitions by default and then skip it wherever required.
|
746
|
+
Please note that only state column will be updated as mentioned in the above example.
|
747
|
+
|
748
|
+
```ruby
|
749
|
+
job.run_without_validation!
|
750
|
+
```
|
751
|
+
|
744
752
|
If you want to make sure that the _AASM_ column for storing the state is not directly assigned,
|
745
753
|
configure _AASM_ to not allow direct assignment, like this:
|
746
754
|
|
@@ -748,12 +756,12 @@ configure _AASM_ to not allow direct assignment, like this:
|
|
748
756
|
class Job < ActiveRecord::Base
|
749
757
|
include AASM
|
750
758
|
|
751
|
-
aasm :
|
752
|
-
state :sleeping, :
|
759
|
+
aasm no_direct_assignment: true do
|
760
|
+
state :sleeping, initial: true
|
753
761
|
state :running
|
754
762
|
|
755
763
|
event :run do
|
756
|
-
transitions :
|
764
|
+
transitions from: :sleeping, to: :running
|
757
765
|
end
|
758
766
|
end
|
759
767
|
|
@@ -784,8 +792,8 @@ class Job < ActiveRecord::Base
|
|
784
792
|
running: 99
|
785
793
|
}
|
786
794
|
|
787
|
-
aasm :
|
788
|
-
state :sleeping, :
|
795
|
+
aasm column: :state, enum: true do
|
796
|
+
state :sleeping, initial: true
|
789
797
|
state :running
|
790
798
|
end
|
791
799
|
end
|
@@ -884,7 +892,7 @@ class Job < ActiveRecord::Base
|
|
884
892
|
include AASM
|
885
893
|
|
886
894
|
aasm do
|
887
|
-
state :sleeping, :
|
895
|
+
state :sleeping, initial: true
|
888
896
|
state :running
|
889
897
|
state :cleaning
|
890
898
|
end
|
@@ -913,8 +921,8 @@ defining the `AASM` states, like this:
|
|
913
921
|
class Job < ActiveRecord::Base
|
914
922
|
include AASM
|
915
923
|
|
916
|
-
aasm :
|
917
|
-
state :sleeping, :
|
924
|
+
aasm create_scopes: false do
|
925
|
+
state :sleeping, initial: true
|
918
926
|
state :running
|
919
927
|
state :cleaning
|
920
928
|
end
|
@@ -947,11 +955,11 @@ class Job < ActiveRecord::Base
|
|
947
955
|
include AASM
|
948
956
|
|
949
957
|
aasm do
|
950
|
-
state :sleeping, :
|
958
|
+
state :sleeping, initial: true
|
951
959
|
state :running
|
952
960
|
|
953
|
-
event :run, :
|
954
|
-
transitions :
|
961
|
+
event :run, after_commit: :notify_about_running_job do
|
962
|
+
transitions from: :sleeping, to: :running
|
955
963
|
end
|
956
964
|
end
|
957
965
|
|
@@ -977,14 +985,14 @@ If you want to encapsulate state changes within an own transaction, the behavior
|
|
977
985
|
of this nested transaction might be confusing. Take a look at
|
978
986
|
[ActiveRecord Nested Transactions](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)
|
979
987
|
if you want to know more about this. Nevertheless, AASM by default requires a new transaction
|
980
|
-
`transaction(:
|
988
|
+
`transaction(requires_new: true)`. You can override this behavior by changing
|
981
989
|
the configuration
|
982
990
|
|
983
991
|
```ruby
|
984
992
|
class Job < ActiveRecord::Base
|
985
993
|
include AASM
|
986
994
|
|
987
|
-
aasm :
|
995
|
+
aasm requires_new_transaction: false do
|
988
996
|
...
|
989
997
|
end
|
990
998
|
|
@@ -992,7 +1000,7 @@ class Job < ActiveRecord::Base
|
|
992
1000
|
end
|
993
1001
|
```
|
994
1002
|
|
995
|
-
which then leads to `transaction(:
|
1003
|
+
which then leads to `transaction(requires_new: false)`, the Rails default.
|
996
1004
|
|
997
1005
|
Additionally, if you do not want any of your active record actions to be
|
998
1006
|
wrapped in a transaction, you can specify the `use_transactions` flag. This can
|
@@ -1004,7 +1012,7 @@ result of a transaction or callback, even when some error occurs. The
|
|
1004
1012
|
class Job < ActiveRecord::Base
|
1005
1013
|
include AASM
|
1006
1014
|
|
1007
|
-
aasm :
|
1015
|
+
aasm use_transactions: false do
|
1008
1016
|
...
|
1009
1017
|
end
|
1010
1018
|
|
@@ -1027,7 +1035,7 @@ AASM supports [Active Record pessimistic locking via `with_lock`](http://api.rub
|
|
1027
1035
|
class Job < ActiveRecord::Base
|
1028
1036
|
include AASM
|
1029
1037
|
|
1030
|
-
aasm :
|
1038
|
+
aasm requires_lock: true do
|
1031
1039
|
...
|
1032
1040
|
end
|
1033
1041
|
|
@@ -1039,7 +1047,7 @@ end
|
|
1039
1047
|
class Job < ActiveRecord::Base
|
1040
1048
|
include AASM
|
1041
1049
|
|
1042
|
-
aasm :
|
1050
|
+
aasm requires_lock: 'FOR UPDATE NOWAIT' do
|
1043
1051
|
...
|
1044
1052
|
end
|
1045
1053
|
|
@@ -1057,11 +1065,11 @@ this by defining your favorite column name, using `:column` like this:
|
|
1057
1065
|
class Job < ActiveRecord::Base
|
1058
1066
|
include AASM
|
1059
1067
|
|
1060
|
-
aasm :
|
1068
|
+
aasm column: :my_state do
|
1061
1069
|
...
|
1062
1070
|
end
|
1063
1071
|
|
1064
|
-
aasm :another_state_machine, column:
|
1072
|
+
aasm :another_state_machine, column: :second_state do
|
1065
1073
|
...
|
1066
1074
|
end
|
1067
1075
|
end
|
@@ -1082,6 +1090,13 @@ class AddJobState < ActiveRecord::Migration
|
|
1082
1090
|
end
|
1083
1091
|
```
|
1084
1092
|
|
1093
|
+
### Log State Changes
|
1094
|
+
|
1095
|
+
Logging state change can be done using [paper_trail](https://github.com/paper-trail-gem/paper_trail) gem
|
1096
|
+
|
1097
|
+
Example of implementation can be found here [https://github.com/nitsujri/aasm-papertrail-example](https://github.com/nitsujri/aasm-papertrail-example)
|
1098
|
+
|
1099
|
+
|
1085
1100
|
### Inspection
|
1086
1101
|
|
1087
1102
|
AASM supports query methods for states and events
|
@@ -1093,19 +1108,19 @@ class Job
|
|
1093
1108
|
include AASM
|
1094
1109
|
|
1095
1110
|
aasm do
|
1096
|
-
state :sleeping, :
|
1111
|
+
state :sleeping, initial: true
|
1097
1112
|
state :running, :cleaning
|
1098
1113
|
|
1099
1114
|
event :run do
|
1100
|
-
transitions :
|
1115
|
+
transitions from: :sleeping, to: :running
|
1101
1116
|
end
|
1102
1117
|
|
1103
1118
|
event :clean do
|
1104
|
-
transitions :
|
1119
|
+
transitions from: :running, to: :cleaning, guard: :cleaning_needed?
|
1105
1120
|
end
|
1106
1121
|
|
1107
1122
|
event :sleep do
|
1108
|
-
transitions :
|
1123
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
1109
1124
|
end
|
1110
1125
|
end
|
1111
1126
|
|
@@ -1123,15 +1138,19 @@ Job.aasm.states.map(&:name)
|
|
1123
1138
|
job = Job.new
|
1124
1139
|
|
1125
1140
|
# show all permitted states (from initial state)
|
1126
|
-
job.aasm.states(:
|
1141
|
+
job.aasm.states(permitted: true).map(&:name)
|
1127
1142
|
#=> [:running]
|
1128
1143
|
|
1144
|
+
# List all the permitted transitions(event and state pairs) from initial state
|
1145
|
+
job.aasm.permitted_transitions
|
1146
|
+
#=> [{ :event => :run, :state => :running }]
|
1147
|
+
|
1129
1148
|
job.run
|
1130
|
-
job.aasm.states(:
|
1149
|
+
job.aasm.states(permitted: true).map(&:name)
|
1131
1150
|
#=> [:sleeping]
|
1132
1151
|
|
1133
1152
|
# show all non permitted states
|
1134
|
-
job.aasm.states(:
|
1153
|
+
job.aasm.states(permitted: false).map(&:name)
|
1135
1154
|
#=> [:cleaning]
|
1136
1155
|
|
1137
1156
|
# show all possible (triggerable) events from the current state
|
@@ -1139,23 +1158,23 @@ job.aasm.events.map(&:name)
|
|
1139
1158
|
#=> [:clean, :sleep]
|
1140
1159
|
|
1141
1160
|
# show all permitted events
|
1142
|
-
job.aasm.events(:
|
1161
|
+
job.aasm.events(permitted: true).map(&:name)
|
1143
1162
|
#=> [:sleep]
|
1144
1163
|
|
1145
1164
|
# show all non permitted events
|
1146
|
-
job.aasm.events(:
|
1165
|
+
job.aasm.events(permitted: false).map(&:name)
|
1147
1166
|
#=> [:clean]
|
1148
1167
|
|
1149
1168
|
# show all possible events except a specific one
|
1150
|
-
job.aasm.events(:
|
1169
|
+
job.aasm.events(reject: :sleep).map(&:name)
|
1151
1170
|
#=> [:clean]
|
1152
1171
|
|
1153
1172
|
# list states for select
|
1154
1173
|
Job.aasm.states_for_select
|
1155
|
-
|
1174
|
+
#=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
|
1156
1175
|
|
1157
1176
|
# show permitted states with guard parameter
|
1158
|
-
job.aasm.states({:
|
1177
|
+
job.aasm.states({permitted: true}, guard_parameter).map(&:name)
|
1159
1178
|
```
|
1160
1179
|
|
1161
1180
|
|
@@ -1168,7 +1187,7 @@ use
|
|
1168
1187
|
class Job
|
1169
1188
|
include AASM
|
1170
1189
|
|
1171
|
-
aasm :
|
1190
|
+
aasm logger: Rails.logger do
|
1172
1191
|
...
|
1173
1192
|
end
|
1174
1193
|
end
|
@@ -1192,12 +1211,12 @@ the 'instance method symbol / string' way whenever possible when defining guardi
|
|
1192
1211
|
|
1193
1212
|
#### RSpec
|
1194
1213
|
|
1195
|
-
AASM provides some matchers for [RSpec](http://rspec.info):
|
1196
|
-
|
1214
|
+
AASM provides some matchers for [RSpec](http://rspec.info):
|
1215
|
+
* `transition_from`,
|
1197
1216
|
* `have_state`, `allow_event`
|
1198
|
-
* and `allow_transition_to`.
|
1217
|
+
* and `allow_transition_to`.
|
1199
1218
|
|
1200
|
-
##### Installation Instructions:
|
1219
|
+
##### Installation Instructions:
|
1201
1220
|
* Add `require 'aasm/rspec'` to your `spec_helper.rb` file.
|
1202
1221
|
|
1203
1222
|
##### Examples Of Usage in Rspec:
|