aasm 5.0.3 → 5.0.8
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 +5 -5
- 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 +28 -9
- data/aasm.gemspec +2 -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 -15
- data/lib/aasm/core/event.rb +3 -3
- data/lib/aasm/instance_base.rb +15 -3
- 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/rspec/transition_from.rb +5 -1
- data/lib/aasm/version.rb +1 -1
- data/spec/database.rb +5 -0
- data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
- data/spec/models/active_record/person.rb +3 -3
- 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/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 +26 -4
- data/spec/unit/rspec_matcher_spec.rb +3 -0
- data/spec/unit/simple_example_spec.rb +15 -0
- metadata +37 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c02be243049ac08482ee6dd9de9b388d7f965019012f680507b75aee43e1819c
|
4
|
+
data.tar.gz: e41809b4fd44cd1d5358e4da499c6b2691caf6a2b6f0b1cf24816458af711522
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5e49eeff60a68201dccfd988525030946a5f4e2ff080a8818ec729f7bb88291b6f333ccf8666a241dfb72b38a2f30333afbc4d284c3c6103eaab49446630b8e
|
7
|
+
data.tar.gz: d2d16d9368d1c8dfd8f50baaea1f07b525798a017fc612c27705161606ae27e1cdd1ea15b979d6d916cfd8abaa81479ff20c72577f8dbbd140dcb78572683845
|
@@ -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.8
|
6
|
+
|
7
|
+
* Revert Fix for :after_commit within nested transaction because it adds after_commit_action dependency which is dependent on many gems.
|
8
|
+
|
9
|
+
## 5.0.7
|
10
|
+
|
11
|
+
* Fix :after_commit within nested transaction [#666](https://github.com/aasm/aasm/pull/666), thanks to [stokarenko](https://github.com/stokarenko)
|
12
|
+
* Add permitted_transitions to group permitted event with state [#664](https://github.com/aasm/aasm/pull/664), thanks to [dnamsons](https://github.com/dnamsons)
|
13
|
+
* 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)
|
14
|
+
* Handle InvalidTransition in transition_from matcher [#653](https://github.com/aasm/aasm/pull/653), thanks to [ryanwood](https://github.com/ryanwood)
|
15
|
+
|
16
|
+
## 5.0.6
|
17
|
+
|
18
|
+
* Fix no_direct_assignment, couldn't be turned off pragmatically [#636](https://github.com/aasm/aasm/issues/636)
|
19
|
+
* Add instance level validation skip option [#644](https://github.com/aasm/aasm/pull/644), thanks to [Nitin-Salunke](https://github.com/Nitin-Salunke)
|
20
|
+
* 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)
|
21
|
+
* Code Refactor [#634](https://github.com/aasm/aasm/pull/634) , thanks to [rahulknojha](https://github.com/rahulknojha)
|
22
|
+
* Fixed callback argument for :before_success & :success callback, [#630](https://github.com/aasm/aasm/pull/630)
|
23
|
+
|
24
|
+
## 5.0.5
|
25
|
+
|
26
|
+
* Independent of ActiveSupport methods, [#627](https://github.com/aasm/aasm/pull/627),
|
27
|
+
thanks to [tristandruyen](https://github.com/tristandruyen). Fixes [#508](https://github.com/aasm/aasm/issues/508)
|
28
|
+
|
29
|
+
## 5.0.4
|
30
|
+
|
31
|
+
* Specify dynamoid version for Rails > 5, [#625](https://github.com/aasm/aasm/pull/625),
|
32
|
+
thanks to [waghanza](https://github.com/waghanza)
|
33
|
+
* Add travis runner for Rails 5.2, [#624](https://github.com/aasm/aasm/pull/624), thanks
|
34
|
+
to [waghanza](https://github.com/waghanza)
|
35
|
+
* Cleanup Abstract class issue, [#620](https://github.com/aasm/aasm/pull/620), thanks to
|
36
|
+
[dennym](https://github.com/dennym)
|
37
|
+
|
5
38
|
## 5.0.3
|
6
39
|
|
7
40
|
* Fix Abstract class issue, [#619](https://github.com/aasm/aasm/pull/619)
|
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)
|
@@ -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
|
|
@@ -436,12 +436,12 @@ 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
|
444
|
+
aasm(:move, column: 'move_state') do
|
445
445
|
state :standing, initial: true
|
446
446
|
state :walking
|
447
447
|
state :running
|
@@ -457,7 +457,7 @@ class SimpleMultipleExample
|
|
457
457
|
end
|
458
458
|
end
|
459
459
|
|
460
|
-
aasm(:work) do
|
460
|
+
aasm(:work, column: 'work_state') do
|
461
461
|
state :sleeping, initial: true
|
462
462
|
state :processing
|
463
463
|
|
@@ -741,6 +741,14 @@ class Job < ActiveRecord::Base
|
|
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
|
|
@@ -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 column:
|
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
|
@@ -1126,6 +1141,10 @@ job = Job.new
|
|
1126
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
1149
|
job.aasm.states(permitted: true).map(&:name)
|
1131
1150
|
#=> [:sleeping]
|
@@ -1193,7 +1212,7 @@ the 'instance method symbol / string' way whenever possible when defining guardi
|
|
1193
1212
|
#### RSpec
|
1194
1213
|
|
1195
1214
|
AASM provides some matchers for [RSpec](http://rspec.info):
|
1196
|
-
|
1215
|
+
* `transition_from`,
|
1197
1216
|
* `have_state`, `allow_event`
|
1198
1217
|
* and `allow_transition_to`.
|
1199
1218
|
|
data/aasm.gemspec
CHANGED
@@ -23,6 +23,8 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_development_dependency 'rspec', ">= 3"
|
24
24
|
s.add_development_dependency 'generator_spec'
|
25
25
|
s.add_development_dependency 'appraisal'
|
26
|
+
s.add_development_dependency "simplecov"
|
27
|
+
s.add_development_dependency "codecov", ">= 0.1.10"
|
26
28
|
|
27
29
|
# debugging
|
28
30
|
# s.add_development_dependency 'debugger'
|
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/aasm.rb
CHANGED
@@ -99,25 +99,10 @@ private
|
|
99
99
|
begin
|
100
100
|
old_state = aasm(state_machine_name).state_object_for_name(aasm(state_machine_name).current_state)
|
101
101
|
|
102
|
-
event.
|
103
|
-
:before_all_events,
|
104
|
-
self,
|
105
|
-
*process_args(event, aasm(state_machine_name).current_state, *args)
|
106
|
-
)
|
107
|
-
|
108
|
-
# new event before callback
|
109
|
-
event.fire_callbacks(
|
110
|
-
:before,
|
111
|
-
self,
|
112
|
-
*process_args(event, aasm(state_machine_name).current_state, *args)
|
113
|
-
)
|
102
|
+
fire_default_callbacks(event, *process_args(event, aasm(state_machine_name).current_state, *args))
|
114
103
|
|
115
104
|
if may_fire_to = event.may_fire?(self, *args)
|
116
|
-
old_state
|
117
|
-
*process_args(event, aasm(state_machine_name).current_state, *args))
|
118
|
-
old_state.fire_callbacks(:exit, self,
|
119
|
-
*process_args(event, aasm(state_machine_name).current_state, *args))
|
120
|
-
|
105
|
+
fire_exit_callbacks(old_state, *process_args(event, aasm(state_machine_name).current_state, *args))
|
121
106
|
if new_state_name = event.fire(self, {:may_fire => may_fire_to}, *args)
|
122
107
|
aasm_fired(state_machine_name, event, old_state, new_state_name, options, *args, &block)
|
123
108
|
else
|
@@ -137,25 +122,44 @@ private
|
|
137
122
|
end
|
138
123
|
end
|
139
124
|
|
125
|
+
def fire_default_callbacks(event, *processed_args)
|
126
|
+
event.fire_global_callbacks(
|
127
|
+
:before_all_events,
|
128
|
+
self,
|
129
|
+
*processed_args
|
130
|
+
)
|
131
|
+
|
132
|
+
# new event before callback
|
133
|
+
event.fire_callbacks(
|
134
|
+
:before,
|
135
|
+
self,
|
136
|
+
*processed_args
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
def fire_exit_callbacks(old_state, *processed_args)
|
141
|
+
old_state.fire_callbacks(:before_exit, self, *processed_args)
|
142
|
+
old_state.fire_callbacks(:exit, self, *processed_args)
|
143
|
+
end
|
144
|
+
|
140
145
|
def aasm_fired(state_machine_name, event, old_state, new_state_name, options, *args)
|
141
146
|
persist = options[:persist]
|
142
147
|
|
143
148
|
new_state = aasm(state_machine_name).state_object_for_name(new_state_name)
|
149
|
+
callback_args = process_args(event, aasm(state_machine_name).current_state, *args)
|
144
150
|
|
145
|
-
new_state.fire_callbacks(:before_enter, self,
|
146
|
-
*process_args(event, aasm(state_machine_name).current_state, *args))
|
151
|
+
new_state.fire_callbacks(:before_enter, self, *callback_args)
|
147
152
|
|
148
|
-
new_state.fire_callbacks(:enter, self,
|
149
|
-
*process_args(event, aasm(state_machine_name).current_state, *args)) # TODO: remove for AASM 4?
|
153
|
+
new_state.fire_callbacks(:enter, self, *callback_args) # TODO: remove for AASM 4?
|
150
154
|
|
151
155
|
persist_successful = true
|
152
156
|
if persist
|
153
157
|
persist_successful = aasm(state_machine_name).set_current_state_with_persistence(new_state_name)
|
154
158
|
if persist_successful
|
155
159
|
yield if block_given?
|
156
|
-
event.fire_callbacks(:before_success, self)
|
160
|
+
event.fire_callbacks(:before_success, self, *callback_args)
|
157
161
|
event.fire_transition_callbacks(self, *process_args(event, old_state.name, *args))
|
158
|
-
event.fire_callbacks(:success, self)
|
162
|
+
event.fire_callbacks(:success, self, *callback_args)
|
159
163
|
end
|
160
164
|
else
|
161
165
|
aasm(state_machine_name).current_state = new_state_name
|
@@ -168,10 +172,8 @@ private
|
|
168
172
|
end
|
169
173
|
|
170
174
|
if persist_successful
|
171
|
-
old_state.fire_callbacks(:after_exit, self,
|
172
|
-
|
173
|
-
new_state.fire_callbacks(:after_enter, self,
|
174
|
-
*process_args(event, aasm(state_machine_name).current_state, *args))
|
175
|
+
old_state.fire_callbacks(:after_exit, self, *callback_args)
|
176
|
+
new_state.fire_callbacks(:after_enter, self, *callback_args)
|
175
177
|
event.fire_callbacks(
|
176
178
|
:after,
|
177
179
|
self,
|
data/lib/aasm/base.rb
CHANGED
@@ -54,25 +54,18 @@ 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
|
-
'direct assignment of AASM column has been disabled (see AASM configuration for this class)'
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
+
else
|
63
|
+
super(state_name)
|
64
|
+
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def should_not_define_method(klass)
|
70
|
-
(klass.methods.include?(:abstract_class) &&
|
71
|
-
klass.abstract_class) ||
|
72
|
-
(klass.superclass.methods.include?(:abstract_class) &&
|
73
|
-
klass.superclass.abstract_class)
|
74
|
-
end
|
75
|
-
|
76
69
|
# This method is both a getter and a setter
|
77
70
|
def attribute_name(column_name=nil)
|
78
71
|
if column_name
|
@@ -142,6 +135,8 @@ module AASM
|
|
142
135
|
aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
|
143
136
|
end
|
144
137
|
|
138
|
+
skip_instance_level_validation(event, name, aasm_name, klass)
|
139
|
+
|
145
140
|
# Create aliases for the event methods. Keep the old names to maintain backwards compatibility.
|
146
141
|
if namespace?
|
147
142
|
klass.send(:alias_method, "may_#{name}_#{namespace}?", "may_#{name}?")
|
@@ -257,5 +252,20 @@ module AASM
|
|
257
252
|
end
|
258
253
|
end
|
259
254
|
|
255
|
+
def skip_instance_level_validation(event, name, aasm_name, klass)
|
256
|
+
# Overrides the skip_validation config for an instance (If skip validation is set to false in original config) and
|
257
|
+
# restores it back to the original value after the event is fired.
|
258
|
+
safely_define_method klass, "#{name}_without_validation!", ->(*args, &block) do
|
259
|
+
original_config = AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save
|
260
|
+
begin
|
261
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save = true unless original_config
|
262
|
+
aasm(aasm_name).current_event = :"#{name}!"
|
263
|
+
aasm_fire_event(aasm_name, event, {:persist => true}, *args, &block)
|
264
|
+
ensure
|
265
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save = original_config
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
260
270
|
end
|
261
271
|
end
|
data/lib/aasm/core/event.rb
CHANGED
@@ -131,13 +131,13 @@ module AASM::Core
|
|
131
131
|
|
132
132
|
if to_state == ::AASM::NO_VALUE
|
133
133
|
to_state = nil
|
134
|
-
elsif to_state.respond_to?(:to_sym) && transitions.map(&:to).flatten.include?(to_state.to_sym)
|
135
|
-
# nop, to_state is a valid to-state
|
136
|
-
else
|
134
|
+
elsif !(to_state.respond_to?(:to_sym) && transitions.map(&:to).flatten.include?(to_state.to_sym))
|
137
135
|
# to_state is an argument
|
138
136
|
args.unshift(to_state)
|
139
137
|
to_state = nil
|
140
138
|
end
|
139
|
+
|
140
|
+
# nop, to_state is a valid to-state
|
141
141
|
|
142
142
|
transitions.each do |transition|
|
143
143
|
next if to_state and !Array(transition.to).include?(to_state)
|
data/lib/aasm/instance_base.rb
CHANGED
@@ -78,6 +78,17 @@ module AASM
|
|
78
78
|
events
|
79
79
|
end
|
80
80
|
|
81
|
+
def permitted_transitions
|
82
|
+
events(permitted: true).flat_map do |event|
|
83
|
+
available_transitions = event.transitions_from_state(current_state)
|
84
|
+
allowed_transitions = available_transitions.select { |t| t.allowed?(@instance) }
|
85
|
+
|
86
|
+
allowed_transitions.map do |transition|
|
87
|
+
{ event: event.name, state: transition.to }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
81
92
|
def state_object_for_name(name)
|
82
93
|
obj = @instance.class.aasm(@name).states.find {|s| s.name == name}
|
83
94
|
raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil?
|
@@ -91,7 +102,7 @@ module AASM
|
|
91
102
|
when Proc
|
92
103
|
state.call(@instance)
|
93
104
|
else
|
94
|
-
raise NotImplementedError, "Unrecognized state-type given.
|
105
|
+
raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc."
|
95
106
|
end
|
96
107
|
end
|
97
108
|
|
@@ -104,11 +115,12 @@ module AASM
|
|
104
115
|
end
|
105
116
|
|
106
117
|
def fire(event_name, *args, &block)
|
107
|
-
@instance.send(
|
118
|
+
@instance.send(event_name, *args, &block)
|
108
119
|
end
|
109
120
|
|
110
121
|
def fire!(event_name, *args, &block)
|
111
|
-
|
122
|
+
event_name = event_name.to_s.+("!").to_sym
|
123
|
+
@instance.send(event_name, *args, &block)
|
112
124
|
end
|
113
125
|
|
114
126
|
def set_current_state_with_persistence(state)
|
@@ -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
|
|
@@ -2,7 +2,11 @@ RSpec::Matchers.define :transition_from do |from_state|
|
|
2
2
|
match do |obj|
|
3
3
|
@state_machine_name ||= :default
|
4
4
|
obj.aasm(@state_machine_name).current_state = from_state.to_sym
|
5
|
-
|
5
|
+
begin
|
6
|
+
obj.send(@event, *@args) && obj.aasm(@state_machine_name).current_state == @to_state.to_sym
|
7
|
+
rescue AASM::InvalidTransition
|
8
|
+
false
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
chain :on do |state_machine_name|
|
data/lib/aasm/version.rb
CHANGED
data/spec/database.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
class InstanceLevelSkipValidationExample < ActiveRecord::Base
|
2
|
+
include AASM
|
3
|
+
|
4
|
+
aasm :state do
|
5
|
+
state :new, :initial => true
|
6
|
+
state :draft
|
7
|
+
state :complete
|
8
|
+
|
9
|
+
event :set_draft do
|
10
|
+
transitions from: :new, to: :draft
|
11
|
+
end
|
12
|
+
|
13
|
+
event :complete do
|
14
|
+
transitions from: %i[draft new], to: :complete
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
validates :some_string, presence: true
|
19
|
+
end
|
@@ -1,7 +1,4 @@
|
|
1
1
|
class Base < ActiveRecord::Base
|
2
|
-
self.abstract_class = true
|
3
|
-
self.table_name = 'users'
|
4
|
-
|
5
2
|
include AASM
|
6
3
|
|
7
4
|
aasm column: 'status' do
|
@@ -16,6 +13,9 @@ class Base < ActiveRecord::Base
|
|
16
13
|
transitions from: :active, to: :inactive
|
17
14
|
end
|
18
15
|
end
|
16
|
+
|
17
|
+
self.abstract_class = true
|
18
|
+
self.table_name = 'users'
|
19
19
|
end
|
20
20
|
|
21
21
|
|
@@ -8,7 +8,7 @@ module Callbacks
|
|
8
8
|
state :closed
|
9
9
|
state :out_to_lunch
|
10
10
|
|
11
|
-
event :close, :before => :before_method, :after => :after_method do
|
11
|
+
event :close, :before => :before_method, :after => :after_method, :before_success => :before_success_method, :success => :success_method3 do
|
12
12
|
transitions :to => :closed, :from => [:open], :after => :transition_method, :success => :success_method
|
13
13
|
transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2, :success => :success_method2
|
14
14
|
end
|
@@ -16,6 +16,8 @@ module Callbacks
|
|
16
16
|
|
17
17
|
def before_method(arg); end
|
18
18
|
|
19
|
+
def before_success_method(arg); end
|
20
|
+
|
19
21
|
def after_method(arg); end
|
20
22
|
|
21
23
|
def transition_method(arg); end
|
@@ -26,5 +28,7 @@ module Callbacks
|
|
26
28
|
|
27
29
|
def success_method2(arg); end
|
28
30
|
|
31
|
+
def success_method3(arg); end
|
32
|
+
|
29
33
|
end
|
30
34
|
end
|
@@ -8,7 +8,7 @@ module Callbacks
|
|
8
8
|
state :closed
|
9
9
|
state :out_to_lunch
|
10
10
|
|
11
|
-
event :close, :before => :before_method, :after => :after_method do
|
11
|
+
event :close, :before => :before_method, :after => :after_method, :before_success => :before_success_method, :success => :success_method do
|
12
12
|
transitions :to => :closed, :from => [:open], :after => :transition_method
|
13
13
|
transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2
|
14
14
|
end
|
@@ -16,11 +16,14 @@ module Callbacks
|
|
16
16
|
|
17
17
|
def before_method(arg); end
|
18
18
|
|
19
|
+
def before_success_method(arg); end
|
20
|
+
|
19
21
|
def after_method(arg); end
|
20
22
|
|
21
23
|
def transition_method(arg); end
|
22
24
|
|
23
25
|
def transition_method2(arg); end
|
24
26
|
|
27
|
+
def success_method(arg); end
|
25
28
|
end
|
26
29
|
end
|
@@ -3,11 +3,17 @@ class SimpleExample
|
|
3
3
|
aasm do
|
4
4
|
state :initialised, :initial => true
|
5
5
|
state :filled_out
|
6
|
+
state :denied
|
6
7
|
state :authorised
|
7
8
|
|
8
9
|
event :fill_out do
|
9
10
|
transitions :from => :initialised, :to => :filled_out
|
10
11
|
end
|
12
|
+
|
13
|
+
event :deny do
|
14
|
+
transitions from: :initialised, to: :denied
|
15
|
+
end
|
16
|
+
|
11
17
|
event :authorise do
|
12
18
|
transitions :from => :filled_out, :to => :authorised
|
13
19
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter '/spec/'
|
4
|
+
end
|
5
|
+
|
6
|
+
if ENV['CI'] == 'true'
|
7
|
+
require 'codecov'
|
8
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
9
|
+
end
|
10
|
+
|
1
11
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
2
12
|
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
3
13
|
require 'aasm'
|
@@ -154,6 +154,8 @@ describe 'callbacks for the new DSL' do
|
|
154
154
|
expect(cb).to receive(:before_method).with(:arg1).once.ordered
|
155
155
|
expect(cb).to receive(:transition_method).never
|
156
156
|
expect(cb).to receive(:transition_method2).with(:arg1).once.ordered
|
157
|
+
expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
|
158
|
+
expect(cb).to receive(:success_method).with(:arg1).once.ordered
|
157
159
|
expect(cb).to receive(:after_method).with(:arg1).once.ordered
|
158
160
|
cb.close!(:out_to_lunch, :arg1)
|
159
161
|
|
@@ -161,6 +163,8 @@ describe 'callbacks for the new DSL' do
|
|
161
163
|
some_object = double('some object')
|
162
164
|
expect(cb).to receive(:before_method).with(some_object).once.ordered
|
163
165
|
expect(cb).to receive(:transition_method2).with(some_object).once.ordered
|
166
|
+
expect(cb).to receive(:before_success_method).with(some_object).once.ordered
|
167
|
+
expect(cb).to receive(:success_method).with(some_object).once.ordered
|
164
168
|
expect(cb).to receive(:after_method).with(some_object).once.ordered
|
165
169
|
cb.close!(:out_to_lunch, some_object)
|
166
170
|
end
|
data/spec/unit/callbacks_spec.rb
CHANGED
@@ -315,7 +315,9 @@ describe 'callbacks for the new DSL' do
|
|
315
315
|
expect(cb).to receive(:before_method).with(:arg1).once.ordered
|
316
316
|
expect(cb).to receive(:transition_method).with(:arg1).once.ordered
|
317
317
|
expect(cb).to receive(:transition_method).never
|
318
|
+
expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
|
318
319
|
expect(cb).to receive(:success_method).with(:arg1).once.ordered
|
320
|
+
expect(cb).to receive(:success_method3).with(:arg1).once.ordered
|
319
321
|
expect(cb).to receive(:success_method).never
|
320
322
|
expect(cb).to receive(:after_method).with(:arg1).once.ordered
|
321
323
|
cb.close!(:arg1)
|
@@ -325,7 +327,9 @@ describe 'callbacks for the new DSL' do
|
|
325
327
|
expect(cb).to receive(:before_method).with(some_object).once.ordered
|
326
328
|
expect(cb).to receive(:transition_method).with(some_object).once.ordered
|
327
329
|
expect(cb).to receive(:transition_method).never
|
330
|
+
expect(cb).to receive(:before_success_method).with(some_object).once.ordered
|
328
331
|
expect(cb).to receive(:success_method).with(some_object).once.ordered
|
332
|
+
expect(cb).to receive(:success_method3).with(some_object).once.ordered
|
329
333
|
expect(cb).to receive(:success_method).never
|
330
334
|
expect(cb).to receive(:after_method).with(some_object).once.ordered
|
331
335
|
cb.close!(some_object)
|
data/spec/unit/event_spec.rb
CHANGED
@@ -294,6 +294,19 @@ describe 'current event' do
|
|
294
294
|
pe.wakeup!
|
295
295
|
expect(pe.aasm.current_event).to eql :wakeup!
|
296
296
|
end
|
297
|
+
|
298
|
+
describe "when calling events with fire/fire!" do
|
299
|
+
it "fire should populate aasm.current_event and transition (sleeping to showering)" do
|
300
|
+
pe.aasm.fire(:wakeup)
|
301
|
+
expect(pe.aasm.current_event).to eq :wakeup
|
302
|
+
expect(pe.aasm.current_state).to eq :showering
|
303
|
+
end
|
304
|
+
it "fire! should populate aasm.current_event and transition (sleeping to showering)" do
|
305
|
+
pe.aasm.fire!(:wakeup)
|
306
|
+
expect(pe.aasm.current_event).to eq :wakeup!
|
307
|
+
expect(pe.aasm.current_state).to eq :showering
|
308
|
+
end
|
309
|
+
end
|
297
310
|
end
|
298
311
|
|
299
312
|
describe 'parametrised events' do
|
@@ -359,13 +359,13 @@ if defined?(ActiveRecord)
|
|
359
359
|
|
360
360
|
# allow it temporarily
|
361
361
|
MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = false
|
362
|
-
obj.aasm_state = :
|
363
|
-
expect(obj.aasm_state.to_sym).to eql :
|
362
|
+
obj.aasm_state = :running
|
363
|
+
expect(obj.aasm_state.to_sym).to eql :running
|
364
364
|
|
365
365
|
# and forbid it again
|
366
366
|
MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = true
|
367
|
-
expect {obj.aasm_state = :
|
368
|
-
expect(obj.aasm_state.to_sym).to eql :
|
367
|
+
expect {obj.aasm_state = :pending}.to raise_error(AASM::NoDirectAssignmentError)
|
368
|
+
expect(obj.aasm_state.to_sym).to eql :running
|
369
369
|
end
|
370
370
|
end # direct assignment
|
371
371
|
|
@@ -393,13 +393,13 @@ if defined?(ActiveRecord)
|
|
393
393
|
|
394
394
|
# allow it temporarily
|
395
395
|
NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = false
|
396
|
-
obj.aasm_state = :
|
397
|
-
expect(obj.aasm_state.to_sym).to eql :
|
396
|
+
obj.aasm_state = :running
|
397
|
+
expect(obj.aasm_state.to_sym).to eql :running
|
398
398
|
|
399
399
|
# and forbid it again
|
400
400
|
NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = true
|
401
|
-
expect {obj.aasm_state = :
|
402
|
-
expect(obj.aasm_state.to_sym).to eql :
|
401
|
+
expect {obj.aasm_state = :pending}.to raise_error(AASM::NoDirectAssignmentError)
|
402
|
+
expect(obj.aasm_state.to_sym).to eql :running
|
403
403
|
end
|
404
404
|
end # direct assignment
|
405
405
|
|
@@ -748,4 +748,26 @@ if defined?(ActiveRecord)
|
|
748
748
|
expect { job.run }.to raise_error(AASM::InvalidTransition)
|
749
749
|
end
|
750
750
|
end
|
751
|
+
|
752
|
+
describe 'testing the instance_level skip validation with _without_validation method' do
|
753
|
+
let(:example) do
|
754
|
+
obj = InstanceLevelSkipValidationExample.new(state: 'new')
|
755
|
+
obj.save(validate: false)
|
756
|
+
obj
|
757
|
+
end
|
758
|
+
|
759
|
+
it 'should be able to change the state with invalid record' do
|
760
|
+
expect(example.valid?).to be_falsey
|
761
|
+
expect(example.complete!).to be_falsey
|
762
|
+
expect(example.complete_without_validation!).to be_truthy
|
763
|
+
expect(example.state).to eq('complete')
|
764
|
+
end
|
765
|
+
|
766
|
+
it 'shouldn\'t affect the behaviour of existing method after calling _without_validation! method' do
|
767
|
+
expect(example.set_draft!).to be_falsey
|
768
|
+
expect(example.set_draft_without_validation!).to be_truthy
|
769
|
+
expect(example.state).to eq('draft')
|
770
|
+
expect(example.complete!).to be_falsey
|
771
|
+
end
|
772
|
+
end
|
751
773
|
end
|
@@ -8,14 +8,17 @@ describe 'state machine' do
|
|
8
8
|
it "works for simple state machines" do
|
9
9
|
expect(simple).to transition_from(:initialised).to(:filled_out).on_event(:fill_out)
|
10
10
|
expect(simple).to_not transition_from(:initialised).to(:authorised).on_event(:fill_out)
|
11
|
+
expect(simple).to_not transition_from(:authorised).to(:filled_out).on_event(:fill_out)
|
11
12
|
end
|
12
13
|
|
13
14
|
it "works for multiple state machines" do
|
14
15
|
expect(multiple).to transition_from(:standing).to(:walking).on_event(:walk).on(:move)
|
15
16
|
expect(multiple).to_not transition_from(:standing).to(:running).on_event(:walk).on(:move)
|
17
|
+
expect(multiple).to_not transition_from(:running).to(:walking).on_event(:walk).on(:move)
|
16
18
|
|
17
19
|
expect(multiple).to transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
|
18
20
|
expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
|
21
|
+
expect(multiple).to_not transition_from(:processing).to(:sleeping).on_event(:start).on(:work)
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
@@ -23,6 +23,21 @@ describe 'state machine' do
|
|
23
23
|
expect(simple).to be_authorised
|
24
24
|
end
|
25
25
|
|
26
|
+
it 'shows the permitted transitions' do
|
27
|
+
expect(simple.aasm.permitted_transitions).to eq(
|
28
|
+
[
|
29
|
+
{ event: :fill_out, state: :filled_out },
|
30
|
+
{ event: :deny, state: :denied }
|
31
|
+
]
|
32
|
+
)
|
33
|
+
|
34
|
+
simple.fill_out!
|
35
|
+
expect(simple.aasm.permitted_transitions).to eq([{ event: :authorise, state: :authorised }])
|
36
|
+
|
37
|
+
simple.authorise
|
38
|
+
expect(simple.aasm.permitted_transitions).to eq([])
|
39
|
+
end
|
40
|
+
|
26
41
|
it 'denies transitions to other states' do
|
27
42
|
expect {simple.authorise}.to raise_error(AASM::InvalidTransition)
|
28
43
|
expect {simple.authorise!}.to raise_error(AASM::InvalidTransition)
|
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.8
|
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:
|
12
|
+
date: 2020-03-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: concurrent-ruby
|
@@ -95,6 +95,34 @@ dependencies:
|
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: simplecov
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: codecov
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 0.1.10
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.1.10
|
98
126
|
- !ruby/object:Gem::Dependency
|
99
127
|
name: pry
|
100
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,6 +145,8 @@ extensions: []
|
|
117
145
|
extra_rdoc_files: []
|
118
146
|
files:
|
119
147
|
- ".document"
|
148
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
149
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
120
150
|
- ".gitignore"
|
121
151
|
- ".travis.yml"
|
122
152
|
- API
|
@@ -137,6 +167,7 @@ files:
|
|
137
167
|
- aasm.gemspec
|
138
168
|
- callbacks.txt
|
139
169
|
- docker-compose.yml
|
170
|
+
- gemfiles/norails.gemfile
|
140
171
|
- gemfiles/rails_3.2.gemfile
|
141
172
|
- gemfiles/rails_4.2.gemfile
|
142
173
|
- gemfiles/rails_4.2_mongoid_5.gemfile
|
@@ -144,6 +175,7 @@ files:
|
|
144
175
|
- gemfiles/rails_5.0.gemfile
|
145
176
|
- gemfiles/rails_5.0_nobrainer.gemfile
|
146
177
|
- gemfiles/rails_5.1.gemfile
|
178
|
+
- gemfiles/rails_5.2.gemfile
|
147
179
|
- lib/aasm.rb
|
148
180
|
- lib/aasm/aasm.rb
|
149
181
|
- lib/aasm/base.rb
|
@@ -205,6 +237,7 @@ files:
|
|
205
237
|
- spec/models/active_record/derivate_new_dsl.rb
|
206
238
|
- spec/models/active_record/false_state.rb
|
207
239
|
- spec/models/active_record/gate.rb
|
240
|
+
- spec/models/active_record/instance_level_skip_validation_example.rb
|
208
241
|
- spec/models/active_record/invalid_persistor.rb
|
209
242
|
- spec/models/active_record/localizer_test_model.rb
|
210
243
|
- spec/models/active_record/no_direct_assignment.rb
|
@@ -390,8 +423,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
390
423
|
- !ruby/object:Gem::Version
|
391
424
|
version: '0'
|
392
425
|
requirements: []
|
393
|
-
|
394
|
-
rubygems_version: 2.6.14
|
426
|
+
rubygems_version: 3.1.2
|
395
427
|
signing_key:
|
396
428
|
specification_version: 4
|
397
429
|
summary: State machine mixin for Ruby objects
|
@@ -408,6 +440,7 @@ test_files:
|
|
408
440
|
- spec/models/active_record/derivate_new_dsl.rb
|
409
441
|
- spec/models/active_record/false_state.rb
|
410
442
|
- spec/models/active_record/gate.rb
|
443
|
+
- spec/models/active_record/instance_level_skip_validation_example.rb
|
411
444
|
- spec/models/active_record/invalid_persistor.rb
|
412
445
|
- spec/models/active_record/localizer_test_model.rb
|
413
446
|
- spec/models/active_record/no_direct_assignment.rb
|