aasm 4.12.3 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 +48 -18
- data/Appraisals +50 -26
- data/CHANGELOG.md +75 -3
- data/Dockerfile +44 -0
- data/Gemfile +2 -3
- data/README.md +216 -110
- data/aasm.gemspec +2 -0
- data/docker-compose.yml +40 -0
- data/gemfiles/norails.gemfile +10 -0
- data/gemfiles/rails_4.2.gemfile +9 -8
- data/gemfiles/rails_4.2_mongoid_5.gemfile +6 -5
- data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +6 -6
- data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +14 -0
- data/gemfiles/rails_5.2.gemfile +14 -0
- data/lib/aasm.rb +5 -2
- data/lib/aasm/aasm.rb +30 -27
- data/lib/aasm/base.rb +25 -7
- data/lib/aasm/core/event.rb +14 -24
- data/lib/aasm/core/invoker.rb +129 -0
- data/lib/aasm/core/invokers/base_invoker.rb +75 -0
- data/lib/aasm/core/invokers/class_invoker.rb +52 -0
- data/lib/aasm/core/invokers/literal_invoker.rb +47 -0
- data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
- data/lib/aasm/core/state.rb +10 -9
- data/lib/aasm/core/transition.rb +7 -68
- data/lib/aasm/errors.rb +4 -3
- data/lib/aasm/instance_base.rb +16 -4
- data/lib/aasm/persistence.rb +3 -0
- data/lib/aasm/persistence/active_record_persistence.rb +25 -5
- 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 +105 -0
- data/lib/aasm/persistence/orm.rb +23 -19
- data/lib/aasm/persistence/plain_persistence.rb +2 -1
- data/lib/aasm/persistence/redis_persistence.rb +1 -1
- data/lib/aasm/persistence/sequel_persistence.rb +0 -1
- data/lib/aasm/rspec/allow_event.rb +5 -1
- data/lib/aasm/rspec/allow_transition_to.rb +5 -1
- data/lib/aasm/rspec/transition_from.rb +5 -1
- data/lib/aasm/version.rb +1 -1
- data/lib/generators/aasm/orm_helpers.rb +6 -0
- data/lib/generators/active_record/aasm_generator.rb +3 -1
- data/lib/generators/nobrainer/aasm_generator.rb +28 -0
- data/lib/motion-aasm.rb +1 -0
- data/spec/database.rb +16 -1
- data/spec/en.yml +0 -3
- data/spec/generators/active_record_generator_spec.rb +6 -0
- data/spec/generators/no_brainer_generator_spec.rb +29 -0
- data/spec/{en_deprecated_style.yml → localizer_test_model_deprecated_style.yml} +0 -4
- data/spec/localizer_test_model_new_style.yml +5 -0
- data/spec/models/active_record/active_record_callback.rb +93 -0
- data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
- data/spec/models/active_record/localizer_test_model.rb +3 -3
- data/spec/models/active_record/person.rb +23 -0
- data/spec/models/active_record/simple_new_dsl.rb +15 -0
- data/spec/models/active_record/work.rb +3 -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/default_state.rb +1 -1
- data/spec/models/nobrainer/complex_no_brainer_example.rb +36 -0
- data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +39 -0
- data/spec/models/nobrainer/no_scope_no_brainer.rb +21 -0
- data/spec/models/nobrainer/nobrainer_relationships.rb +25 -0
- data/spec/models/nobrainer/silent_persistor_no_brainer.rb +39 -0
- data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +25 -0
- data/spec/models/nobrainer/simple_no_brainer.rb +23 -0
- data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
- data/spec/models/simple_example.rb +8 -0
- data/spec/models/simple_example_with_guard_args.rb +17 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/spec_helpers/active_record.rb +2 -1
- data/spec/spec_helpers/dynamoid.rb +7 -5
- data/spec/spec_helpers/mongoid.rb +20 -1
- data/spec/spec_helpers/nobrainer.rb +15 -0
- data/spec/spec_helpers/redis.rb +5 -2
- data/spec/spec_helpers/sequel.rb +1 -1
- data/spec/unit/abstract_class_spec.rb +27 -0
- data/spec/unit/api_spec.rb +4 -0
- data/spec/unit/callback_multiple_spec.rb +7 -3
- data/spec/unit/callbacks_spec.rb +32 -2
- data/spec/unit/complex_example_spec.rb +0 -1
- data/spec/unit/event_spec.rb +13 -0
- data/spec/unit/exception_spec.rb +1 -1
- data/spec/unit/inspection_multiple_spec.rb +9 -5
- data/spec/unit/inspection_spec.rb +7 -3
- data/spec/unit/invoker_spec.rb +189 -0
- data/spec/unit/invokers/base_invoker_spec.rb +72 -0
- data/spec/unit/invokers/class_invoker_spec.rb +95 -0
- data/spec/unit/invokers/literal_invoker_spec.rb +86 -0
- data/spec/unit/invokers/proc_invoker_spec.rb +86 -0
- data/spec/unit/localizer_spec.rb +9 -10
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +4 -4
- data/spec/unit/persistence/active_record_persistence_spec.rb +109 -4
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -4
- data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -4
- data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +198 -0
- data/spec/unit/persistence/no_brainer_persistence_spec.rb +158 -0
- data/spec/unit/rspec_matcher_spec.rb +9 -0
- data/spec/unit/simple_example_spec.rb +15 -0
- data/spec/unit/state_spec.rb +23 -7
- data/spec/unit/transition_spec.rb +1 -1
- data/test/minitest_helper.rb +2 -2
- data/test/unit/minitest_matcher_test.rb +1 -1
- metadata +106 -12
- data/callbacks.txt +0 -51
- data/gemfiles/rails_3.2.gemfile +0 -13
- data/gemfiles/rails_4.0.gemfile +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f2f4099a66f8d753c2bd7c06b3c378dcd37b47acf9b2f7487784e7762742c1c4
|
4
|
+
data.tar.gz: 8971b36f1b066c08d3a4d278a99d7c1e5386be72182da62b51a82db1e60e9e9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c24e544b82cfc4616f3e3ff033b7a5ab68bff7bd834b115797e9127ca361effe241ffb1adaedcdb595711a6757f2e0a8e0a8d606a9bc812c28707a1ee845ef40
|
7
|
+
data.tar.gz: 421636d1e59e52b8d6b4ddff7dd373fecd9a19ef67b90935e856b1ee980bae9a5a4a8526e62238de9ecc84a7783362e8d5b2005c53b9c7754368be79724c6255
|
@@ -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,23 +2,37 @@ sudo: false
|
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
4
|
|
5
|
+
jdk:
|
6
|
+
- openjdk8
|
7
|
+
|
8
|
+
before_install:
|
9
|
+
- rvm list
|
10
|
+
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
11
|
+
- gem install bundler -v '1.16.1'
|
12
|
+
- bundle _1.16.1_ install
|
13
|
+
|
5
14
|
rvm:
|
6
|
-
-
|
7
|
-
- 2.
|
8
|
-
- 2.
|
9
|
-
- jruby-
|
10
|
-
- jruby-9.0.5.0
|
15
|
+
- 2.5.0
|
16
|
+
- 2.6.5
|
17
|
+
- 2.7.0
|
18
|
+
- jruby-9.1.12.0
|
11
19
|
|
12
20
|
services:
|
13
21
|
- mongodb
|
14
22
|
- redis-server
|
15
23
|
|
24
|
+
#addons:
|
25
|
+
# rethinkdb: '2.3.4'
|
26
|
+
|
16
27
|
gemfile:
|
17
|
-
- gemfiles/
|
18
|
-
- gemfiles/rails_4.0.gemfile
|
28
|
+
- gemfiles/norails.gemfile
|
19
29
|
- gemfiles/rails_4.2.gemfile
|
20
30
|
- gemfiles/rails_4.2_mongoid_5.gemfile
|
31
|
+
# - gemfiles/rails_4.2_nobrainer.gemfile
|
21
32
|
- gemfiles/rails_5.0.gemfile
|
33
|
+
# - gemfiles/rails_5.0_nobrainer.gemfile
|
34
|
+
- gemfiles/rails_5.1.gemfile
|
35
|
+
- gemfiles/rails_5.2.gemfile
|
22
36
|
|
23
37
|
before_script:
|
24
38
|
- mkdir /tmp/dynamodb
|
@@ -32,20 +46,36 @@ script:
|
|
32
46
|
|
33
47
|
matrix:
|
34
48
|
exclude:
|
35
|
-
- rvm:
|
49
|
+
- rvm: 2.7.0
|
50
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
51
|
+
- rvm: 2.6.5
|
52
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
53
|
+
- rvm: 2.5.0
|
54
|
+
gemfile: gemfiles/rails_4.2.gemfile
|
55
|
+
- rvm: 2.6.5
|
56
|
+
gemfile: gemfiles/rails_4.2.gemfile
|
57
|
+
- rvm: 2.7.0
|
58
|
+
gemfile: gemfiles/rails_4.2.gemfile
|
59
|
+
- rvm: 2.5.0
|
36
60
|
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
37
|
-
- rvm:
|
38
|
-
gemfile: gemfiles/rails_5.0.gemfile
|
39
|
-
- rvm: 2.2.6
|
40
|
-
gemfile: gemfiles/rails_3.2.gemfile
|
41
|
-
- rvm: 2.3.3
|
42
|
-
gemfile: gemfiles/rails_3.2.gemfile
|
43
|
-
- rvm: jruby-1.7
|
61
|
+
- rvm: 2.6.5
|
44
62
|
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
45
|
-
- rvm:
|
46
|
-
gemfile: gemfiles/
|
47
|
-
- rvm:
|
63
|
+
- rvm: 2.7.0
|
64
|
+
gemfile: gemfiles/rails_4.2_mongoid_5.gemfile
|
65
|
+
# - rvm: 2.5.0
|
66
|
+
# gemfile: gemfiles/rails_4.2_nobrainer.gemfile
|
67
|
+
- rvm: jruby-9.1.12.0
|
68
|
+
gemfile: gemfiles/norails.gemfile
|
69
|
+
- rvm: jruby-9.1.12.0
|
48
70
|
gemfile: gemfiles/rails_5.0.gemfile
|
71
|
+
- rvm: jruby-9.1.12.0
|
72
|
+
gemfile: gemfiles/rails_5.1.gemfile
|
73
|
+
- rvm: jruby-9.1.12.0
|
74
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
75
|
+
# - rvm: jruby-9.1.12.0
|
76
|
+
# gemfile: gemfiles/rails_4.2_nobrainer.gemfile
|
77
|
+
# - rvm: jruby-9.1.12.0
|
78
|
+
# gemfile: gemfiles/rails_5.0_nobrainer.gemfile
|
49
79
|
|
50
80
|
notifications:
|
51
81
|
slack:
|
data/Appraisals
CHANGED
@@ -1,43 +1,67 @@
|
|
1
|
-
appraise '
|
2
|
-
gem '
|
3
|
-
gem '
|
4
|
-
gem '
|
5
|
-
gem '
|
6
|
-
gem 'test-unit', '~> 3.0'
|
7
|
-
end
|
8
|
-
|
9
|
-
appraise 'rails_4.0' do
|
10
|
-
gem 'mime-types', '~> 2', :platforms => [:ruby_19, :jruby]
|
11
|
-
gem 'rails', '4.0.13'
|
12
|
-
gem 'mongoid', '~>4.0'
|
1
|
+
appraise 'rails_4.2' do
|
2
|
+
gem 'nokogiri', '1.6.8.1', platforms: %i[ruby_19]
|
3
|
+
gem 'mime-types', '~> 2', platforms: %i[ruby_19 jruby]
|
4
|
+
gem 'rails', '4.2.5'
|
5
|
+
gem 'mongoid', '~> 4.0'
|
13
6
|
gem 'sequel'
|
14
|
-
gem 'dynamoid', '~> 1',
|
15
|
-
gem 'aws-sdk', '~>2',
|
7
|
+
gem 'dynamoid', '~> 1', platforms: :ruby
|
8
|
+
gem 'aws-sdk', '~> 2', platforms: :ruby
|
16
9
|
gem 'redis-objects'
|
10
|
+
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
11
|
+
gem "after_commit_everywhere", "~> 0.1", ">= 0.1.5"
|
17
12
|
end
|
18
13
|
|
19
|
-
appraise 'rails_4.
|
20
|
-
gem 'nokogiri', '1.6.8.1', :platforms => [:ruby_19]
|
21
|
-
gem 'mime-types', '~> 2', :platforms => [:ruby_19, :jruby]
|
14
|
+
appraise 'rails_4.2_nobrainer' do
|
22
15
|
gem 'rails', '4.2.5'
|
23
|
-
gem '
|
24
|
-
gem 'sequel'
|
25
|
-
gem 'dynamoid', '~> 1', :platforms => :ruby
|
26
|
-
gem 'aws-sdk', '~>2', :platforms => :ruby
|
27
|
-
gem 'redis-objects'
|
16
|
+
gem 'nobrainer', '~> 0.33.0'
|
28
17
|
end
|
29
18
|
|
30
19
|
appraise 'rails_4.2_mongoid_5' do
|
31
|
-
gem 'mime-types', '~> 2',
|
20
|
+
gem 'mime-types', '~> 2', platforms: %i[ruby_19 jruby]
|
32
21
|
gem 'rails', '4.2.5'
|
33
|
-
gem 'mongoid', '~>5.0'
|
22
|
+
gem 'mongoid', '~> 5.0'
|
23
|
+
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
24
|
+
gem "after_commit_everywhere", "~> 0.1", ">= 0.1.5"
|
34
25
|
end
|
35
26
|
|
36
27
|
appraise 'rails_5.0' do
|
37
28
|
gem 'rails', '5.0.0'
|
29
|
+
gem 'mongoid', '~> 6.0'
|
30
|
+
gem 'sequel'
|
31
|
+
gem 'dynamoid', '~> 1.3', platforms: :ruby
|
32
|
+
gem 'aws-sdk', '~> 2', platforms: :ruby
|
33
|
+
gem 'redis-objects'
|
34
|
+
gem "after_commit_everywhere", "~> 0.1", ">= 0.1.5"
|
35
|
+
end
|
36
|
+
|
37
|
+
appraise 'rails_5.0_nobrainer' do
|
38
|
+
gem 'rails', '5.0.0'
|
39
|
+
gem 'nobrainer', '~> 0.33.0'
|
40
|
+
end
|
41
|
+
|
42
|
+
appraise 'rails_5.1' do
|
43
|
+
gem 'rails', '5.1'
|
44
|
+
gem 'mongoid', '~>6.0'
|
45
|
+
gem 'sequel'
|
46
|
+
gem 'dynamoid', '~> 1.3', platforms: :ruby
|
47
|
+
gem 'aws-sdk', '~>2', platforms: :ruby
|
48
|
+
gem 'redis-objects'
|
49
|
+
gem "after_commit_everywhere", "~> 0.1", ">= 0.1.5"
|
50
|
+
end
|
51
|
+
|
52
|
+
appraise 'rails_5.2' do
|
53
|
+
gem 'rails', '5.2'
|
38
54
|
gem 'mongoid', '~>6.0'
|
39
55
|
gem 'sequel'
|
40
|
-
gem 'dynamoid', '~>
|
41
|
-
gem 'aws-sdk', '~>2',
|
56
|
+
gem 'dynamoid', '~>2.2', platforms: :ruby
|
57
|
+
gem 'aws-sdk', '~>2', platforms: :ruby
|
58
|
+
gem 'redis-objects'
|
59
|
+
gem "after_commit_everywhere", "~> 0.1", ">= 0.1.5"
|
60
|
+
end
|
61
|
+
|
62
|
+
appraise 'norails' do
|
63
|
+
gem 'sqlite3', '~> 1.3', '>= 1.3.5', platforms: :ruby
|
64
|
+
gem 'rails', install_if: false
|
65
|
+
gem 'sequel'
|
42
66
|
gem 'redis-objects'
|
43
67
|
end
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,78 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
3
|
## unreleased
|
4
|
+
|
5
|
+
## 5.1.0
|
6
|
+
|
7
|
+
* Fix Depreciation message for after_commit_everywhere [#695](https://github.com/aasm/aasm/issues/695) in PR [#696](https://github.com/aasm/aasm/pull/696)
|
8
|
+
* Fix human_state to use display option [#684](https://github.com/aasm/aasm/issues/684) in PR [#697](https://github.com/aasm/aasm/pull/697)
|
9
|
+
* Remove support for ruby 2.3
|
10
|
+
|
11
|
+
## 5.1.0
|
12
|
+
|
13
|
+
* Fix after_commit in nested transactions [#536](https://github.com/aasm/aasm/issues/536) without explicit AR dependency in PR [#668](https://github.com/aasm/aasm/pull/668), thanks to [stokarenko](https://github.com/stokarenko)
|
14
|
+
* Remove support for Rails 3.2
|
15
|
+
|
16
|
+
## 5.0.8
|
17
|
+
|
18
|
+
* Revert Fix for :after_commit within nested transaction because it adds after_commit_action dependency which is dependent on many gems.
|
19
|
+
|
20
|
+
## 5.0.7
|
21
|
+
|
22
|
+
* Fix :after_commit within nested transaction [#666](https://github.com/aasm/aasm/pull/666), thanks to [stokarenko](https://github.com/stokarenko)
|
23
|
+
* Add permitted_transitions to group permitted event with state [#664](https://github.com/aasm/aasm/pull/664), thanks to [dnamsons](https://github.com/dnamsons)
|
24
|
+
* 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)
|
25
|
+
* Handle InvalidTransition in transition_from matcher [#653](https://github.com/aasm/aasm/pull/653), thanks to [ryanwood](https://github.com/ryanwood)
|
26
|
+
|
27
|
+
## 5.0.6
|
28
|
+
|
29
|
+
* Fix no_direct_assignment, couldn't be turned off pragmatically [#636](https://github.com/aasm/aasm/issues/636)
|
30
|
+
* Add instance level validation skip option [#644](https://github.com/aasm/aasm/pull/644), thanks to [Nitin-Salunke](https://github.com/Nitin-Salunke)
|
31
|
+
* 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)
|
32
|
+
* Code Refactor [#634](https://github.com/aasm/aasm/pull/634) , thanks to [rahulknojha](https://github.com/rahulknojha)
|
33
|
+
* Fixed callback argument for :before_success & :success callback, [#630](https://github.com/aasm/aasm/pull/630)
|
34
|
+
|
35
|
+
## 5.0.5
|
36
|
+
|
37
|
+
* Independent of ActiveSupport methods, [#627](https://github.com/aasm/aasm/pull/627),
|
38
|
+
thanks to [tristandruyen](https://github.com/tristandruyen). Fixes [#508](https://github.com/aasm/aasm/issues/508)
|
39
|
+
|
40
|
+
## 5.0.4
|
41
|
+
|
42
|
+
* Specify dynamoid version for Rails > 5, [#625](https://github.com/aasm/aasm/pull/625),
|
43
|
+
thanks to [waghanza](https://github.com/waghanza)
|
44
|
+
* Add travis runner for Rails 5.2, [#624](https://github.com/aasm/aasm/pull/624), thanks
|
45
|
+
to [waghanza](https://github.com/waghanza)
|
46
|
+
* Cleanup Abstract class issue, [#620](https://github.com/aasm/aasm/pull/620), thanks to
|
47
|
+
[dennym](https://github.com/dennym)
|
48
|
+
|
49
|
+
## 5.0.3
|
50
|
+
|
51
|
+
* Fix Abstract class issue, [#619](https://github.com/aasm/aasm/pull/619)
|
52
|
+
|
53
|
+
## 5.0.2
|
54
|
+
|
55
|
+
* Clear failed callbacks, [#600](https://github.com/aasm/aasm/pull/600), thanks to
|
56
|
+
[nedgar](https://github.com/nedgar)
|
57
|
+
* README improvements, [#594](https://github.com/aasm/aasm/pull/594),
|
58
|
+
[#589](https://github.com/aasm/aasm/pull/589), [#587](https://github.com/aasm/aasm/pull/587),
|
59
|
+
[#597](https://github.com/aasm/aasm/pull/597), thanks to [jackscotti](https://github.com/jackscotti), [krmbzds](https://github.com/krmbzds),
|
60
|
+
[zegomesjf](https://github.com/zegomesjf), [BKSpurgeon](https://github.com/BKSpurgeon)
|
61
|
+
* Update InvalidTransition to include state_machine_name [#592](https://github.com/aasm/aasm/pull/592), thanks to [a14m](https://github.com/a14m)
|
62
|
+
* Do not add migration if model and column already exists [#586](https://github.com/aasm/aasm/pull/586), thanks to [KiranJosh](https://github.com/KiranJosh)
|
63
|
+
|
64
|
+
## 5.0.1
|
65
|
+
|
66
|
+
* Fix failures array in transition not being reset [#383](https://github.com/aasm/aasm/issues/383)
|
67
|
+
* Enable AASM scopes to be defined on abstract classes.
|
68
|
+
|
69
|
+
## 5.0.0
|
70
|
+
|
71
|
+
* Chore(invokers): Refactor callback invokers, add class-callbacks support [#541](https://github.com/aasm/aasm/pull/541), thanks to [pandomic](https://github.com/pandomic)
|
72
|
+
* Add docker setup to readme
|
73
|
+
* Add support for Nobrainer (RethinkDB) [#522](https://github.com/aasm/aasm/pull/522), thanks to [zedtux](https://github.com/zedtux)
|
74
|
+
* Patch `allow_event` to accept event with custom arguments [#419](https://github.com/aasm/aasm/pull/419), thanks to [czhc](https://github.com/czhc)
|
75
|
+
|
4
76
|
## 4.12.3
|
5
77
|
|
6
78
|
* Add to AASM fire(event) and fire!(event) methods [#494](https://github.com/aasm/aasm/pull/494), thanks to [slayer](https://github.com/slayer)
|
@@ -14,9 +86,9 @@
|
|
14
86
|
|
15
87
|
## 4.12.1
|
16
88
|
|
17
|
-
* DRY-up Mongoid and ActiveRecord Persistence, Add Sequel transactions and locking [#475](https://github.com/aasm/aasm/pull/475), thanks to [@Aryk]
|
18
|
-
* Add aliases for event methods [#476](https://github.com/aasm/aasm/pull/476), thanks to [@Aryk]
|
19
|
-
* Support Minitest spec expectations [#387](https://github.com/aasm/aasm/pull/387), thanks to [@faragorn]
|
89
|
+
* DRY-up Mongoid and ActiveRecord Persistence, Add Sequel transactions and locking [#475](https://github.com/aasm/aasm/pull/475), thanks to [@Aryk](https://github.com/Aryk)
|
90
|
+
* Add aliases for event methods [#476](https://github.com/aasm/aasm/pull/476), thanks to [@Aryk](https://github.com/Aryk)
|
91
|
+
* Support Minitest spec expectations [#387](https://github.com/aasm/aasm/pull/387), thanks to [@faragorn](https://github.com/faragorn)
|
20
92
|
## 4.12.0
|
21
93
|
|
22
94
|
* Fix thread safe issue with concurrent-ruby gem [see [pull-request #422](https://github.com/aasm/aasm/pull/442), thanks to [@reidmorrison](https://github.com/reidmorrison)
|
data/Dockerfile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
FROM ruby:2.3.4-slim
|
2
|
+
|
3
|
+
LABEL maintainer="AASM"
|
4
|
+
|
5
|
+
ENV DEBIAN_FRONTEND noninteractive
|
6
|
+
|
7
|
+
# ~~~~ System locales ~~~~
|
8
|
+
RUN apt-get update && apt-get install -y locales && \
|
9
|
+
dpkg-reconfigure locales && \
|
10
|
+
locale-gen C.UTF-8 && \
|
11
|
+
/usr/sbin/update-locale LANG=C.UTF-8 && \
|
12
|
+
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && \
|
13
|
+
locale-gen
|
14
|
+
|
15
|
+
# Set default locale for the environment
|
16
|
+
ENV LC_ALL C.UTF-8
|
17
|
+
ENV LANG en_US.UTF-8
|
18
|
+
ENV LANGUAGE en_US.UTF-8
|
19
|
+
ENV APP_HOME /application
|
20
|
+
|
21
|
+
# ~~~~ Application dependencies ~~~~
|
22
|
+
RUN apt-get update
|
23
|
+
RUN apt-get install -y libsqlite3-dev \
|
24
|
+
build-essential \
|
25
|
+
git
|
26
|
+
|
27
|
+
# ~~~~ Bundler ~~~~
|
28
|
+
RUN gem install bundler
|
29
|
+
|
30
|
+
WORKDIR $APP_HOME
|
31
|
+
RUN mkdir -p $APP_HOME/lib/aasm/
|
32
|
+
|
33
|
+
COPY Gemfile* $APP_HOME/
|
34
|
+
COPY *.gemspec $APP_HOME/
|
35
|
+
COPY lib/aasm/version.rb $APP_HOME/lib/aasm/
|
36
|
+
|
37
|
+
ENV BUNDLE_GEMFILE=$APP_HOME/Gemfile \
|
38
|
+
BUNDLE_JOBS=8 \
|
39
|
+
BUNDLE_PATH=/bundle
|
40
|
+
|
41
|
+
RUN bundle install
|
42
|
+
|
43
|
+
# ~~~~ Import application ~~~~
|
44
|
+
COPY . $APP_HOME
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/aasm.svg)](http://badge.fury.io/rb/aasm)
|
4
4
|
[![Build Status](https://travis-ci.org/aasm/aasm.svg?branch=master)](https://travis-ci.org/aasm/aasm)
|
5
|
-
[![Dependency Status](https://gemnasium.com/aasm/aasm.svg)](https://gemnasium.com/aasm/aasm)
|
6
5
|
[![Code Climate](https://codeclimate.com/github/aasm/aasm/badges/gpa.svg)](https://codeclimate.com/github/aasm/aasm)
|
6
|
+
[![codecov](https://codecov.io/gh/aasm/aasm/branch/master/graph/badge.svg)](https://codecov.io/gh/aasm/aasm)
|
7
7
|
|
8
8
|
## Index
|
9
9
|
- [Upgrade from version 3 to 4](#upgrade-from-version-3-to-4)
|
@@ -24,11 +24,13 @@
|
|
24
24
|
- [Sequel](#sequel)
|
25
25
|
- [Dynamoid](#dynamoid)
|
26
26
|
- [Mongoid](#mongoid)
|
27
|
+
- [Nobrainer](#nobrainer)
|
27
28
|
- [Redis](#redis)
|
28
29
|
- [Automatic Scopes](#automatic-scopes)
|
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)
|
@@ -42,6 +44,7 @@
|
|
42
44
|
- [Bundler](#or-if-you-are-using-bundler)
|
43
45
|
- [Building your own gems](#building-your-own-gems)
|
44
46
|
- [Generators](#generators)
|
47
|
+
- [Test suite with Docker](#docker)
|
45
48
|
- [Latest changes](#latest-changes)
|
46
49
|
- [Questions?](#questions)
|
47
50
|
- [Maintainers](#maintainers)
|
@@ -52,10 +55,8 @@
|
|
52
55
|
This package contains AASM, a library for adding finite state machines to Ruby classes.
|
53
56
|
|
54
57
|
AASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library
|
55
|
-
that no longer targets only ActiveRecord models. It currently provides adapters for
|
56
|
-
|
57
|
-
and [Mongoid](http://mongoid.org/) but it can be used for any Ruby class, no matter what
|
58
|
-
parent class it has (if any).
|
58
|
+
that no longer targets only ActiveRecord models. It currently provides adapters for many
|
59
|
+
ORMs but it can be used for any Ruby class, no matter what parent class it has (if any).
|
59
60
|
|
60
61
|
## Upgrade from version 3 to 4
|
61
62
|
|
@@ -71,19 +72,19 @@ class Job
|
|
71
72
|
include AASM
|
72
73
|
|
73
74
|
aasm do
|
74
|
-
state :sleeping, :
|
75
|
+
state :sleeping, initial: true
|
75
76
|
state :running, :cleaning
|
76
77
|
|
77
78
|
event :run do
|
78
|
-
transitions :
|
79
|
+
transitions from: :sleeping, to: :running
|
79
80
|
end
|
80
81
|
|
81
82
|
event :clean do
|
82
|
-
transitions :
|
83
|
+
transitions from: :running, to: :cleaning
|
83
84
|
end
|
84
85
|
|
85
86
|
event :sleep do
|
86
|
-
transitions :
|
87
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
@@ -109,7 +110,7 @@ AASM not to be *whiny*:
|
|
109
110
|
```ruby
|
110
111
|
class Job
|
111
112
|
...
|
112
|
-
aasm :
|
113
|
+
aasm whiny_transitions: false do
|
113
114
|
...
|
114
115
|
end
|
115
116
|
end
|
@@ -130,27 +131,27 @@ the transition succeeds :
|
|
130
131
|
|
131
132
|
### Callbacks
|
132
133
|
|
133
|
-
You can define a number of callbacks for your transitions. These methods will be
|
134
|
-
called
|
134
|
+
You can define a number of callbacks for your events, transitions and states. These methods, Procs or classes will be
|
135
|
+
called when certain criteria are met, like entering a particular state:
|
135
136
|
|
136
137
|
```ruby
|
137
138
|
class Job
|
138
139
|
include AASM
|
139
140
|
|
140
141
|
aasm do
|
141
|
-
state :sleeping, :
|
142
|
-
state :running
|
142
|
+
state :sleeping, initial: true, before_enter: :do_something
|
143
|
+
state :running, before_enter: Proc.new { do_something && notify_somebody }
|
143
144
|
state :finished
|
144
145
|
|
145
146
|
after_all_transitions :log_status_change
|
146
147
|
|
147
|
-
event :run, :
|
148
|
+
event :run, after: :notify_somebody do
|
148
149
|
before do
|
149
150
|
log('Preparing to run')
|
150
151
|
end
|
151
152
|
|
152
|
-
transitions :
|
153
|
-
transitions :
|
153
|
+
transitions from: :sleeping, to: :running, after: Proc.new {|*args| set_process(*args) }
|
154
|
+
transitions from: :running, to: :finished, after: LogRunTime
|
154
155
|
end
|
155
156
|
|
156
157
|
event :sleep do
|
@@ -160,7 +161,7 @@ class Job
|
|
160
161
|
error do |e|
|
161
162
|
...
|
162
163
|
end
|
163
|
-
transitions :
|
164
|
+
transitions from: :running, to: :sleeping
|
164
165
|
end
|
165
166
|
end
|
166
167
|
|
@@ -195,6 +196,8 @@ is finished.
|
|
195
196
|
|
196
197
|
AASM will also initialize `LogRunTime` and run the `call` method for you after the transition from `running` to `finished` in the example above. You can pass arguments to the class by defining an initialize method on it, like this:
|
197
198
|
|
199
|
+
Note that Procs are executed in the context of a record, it means that you don't need to expect the record as an argument, just call the methods you need.
|
200
|
+
|
198
201
|
```ruby
|
199
202
|
class LogRunTime
|
200
203
|
# optional args parameter can be omitted, but if you define initialize
|
@@ -213,19 +216,17 @@ Also, you can pass parameters to events:
|
|
213
216
|
|
214
217
|
```ruby
|
215
218
|
job = Job.new
|
216
|
-
job.run(:
|
219
|
+
job.run(:defragmentation)
|
217
220
|
```
|
218
221
|
|
219
222
|
In this case the `set_process` would be called with `:defragmentation` argument.
|
220
223
|
|
221
|
-
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.
|
222
|
-
|
223
224
|
In case of an error during the event processing the error is rescued and passed to `:error`
|
224
225
|
callback, which can handle it or re-raise it for further propagation.
|
225
226
|
|
226
227
|
Also, you can define a method that will be called if any event fails:
|
227
228
|
|
228
|
-
```
|
229
|
+
```ruby
|
229
230
|
def aasm_event_failed(event_name, old_state_name)
|
230
231
|
# use custom exception/messages, report metrics, etc
|
231
232
|
end
|
@@ -259,8 +260,8 @@ begin
|
|
259
260
|
new_state enter
|
260
261
|
...update state...
|
261
262
|
event before_success # if persist successful
|
262
|
-
transition success # if persist successful
|
263
|
-
event success # if persist successful
|
263
|
+
transition success # if persist successful, database update not guaranteed
|
264
|
+
event success # if persist successful, database update not guaranteed
|
264
265
|
old_state after_exit
|
265
266
|
new_state after_enter
|
266
267
|
event after
|
@@ -274,6 +275,8 @@ ensure
|
|
274
275
|
end
|
275
276
|
```
|
276
277
|
|
278
|
+
Use event's `after_commit` callback if it should be fired after database update.
|
279
|
+
|
277
280
|
#### The current event triggered
|
278
281
|
|
279
282
|
While running the callbacks you can easily retrieve the name of the event triggered
|
@@ -311,24 +314,24 @@ class Cleaner
|
|
311
314
|
include AASM
|
312
315
|
|
313
316
|
aasm do
|
314
|
-
state :idle, :
|
317
|
+
state :idle, initial: true
|
315
318
|
state :cleaning
|
316
319
|
|
317
320
|
event :clean do
|
318
|
-
transitions :
|
321
|
+
transitions from: :idle, to: :cleaning, guard: :cleaning_needed?
|
319
322
|
end
|
320
323
|
|
321
324
|
event :clean_if_needed do
|
322
|
-
transitions :
|
325
|
+
transitions from: :idle, to: :cleaning do
|
323
326
|
guard do
|
324
327
|
cleaning_needed?
|
325
328
|
end
|
326
329
|
end
|
327
|
-
transitions :
|
330
|
+
transitions from: :idle, to: :idle
|
328
331
|
end
|
329
332
|
|
330
333
|
event :clean_if_dirty do
|
331
|
-
transitions :
|
334
|
+
transitions from: :idle, to: :cleaning, guard: :if_dirty?
|
332
335
|
end
|
333
336
|
end
|
334
337
|
|
@@ -357,16 +360,16 @@ You can even provide a number of guards, which all have to succeed to proceed
|
|
357
360
|
def walked_the_dog?; ...; end
|
358
361
|
|
359
362
|
event :sleep do
|
360
|
-
transitions :
|
363
|
+
transitions from: :running, to: :sleeping, guards: [:cleaning_needed?, :walked_the_dog?]
|
361
364
|
end
|
362
365
|
```
|
363
366
|
|
364
367
|
If you want to provide guards for all transitions within an event, you can use event guards
|
365
368
|
|
366
369
|
```ruby
|
367
|
-
event :sleep, :
|
368
|
-
transitions :
|
369
|
-
transitions :
|
370
|
+
event :sleep, guards: [:walked_the_dog?] do
|
371
|
+
transitions from: :running, to: :sleeping, guards: [:cleaning_needed?]
|
372
|
+
transitions from: :cleaning, to: :sleeping
|
370
373
|
end
|
371
374
|
```
|
372
375
|
|
@@ -374,15 +377,30 @@ If you prefer a more Ruby-like guard syntax, you can use `if` and `unless` as we
|
|
374
377
|
|
375
378
|
```ruby
|
376
379
|
event :clean do
|
377
|
-
transitions :
|
380
|
+
transitions from: :running, to: :cleaning, if: :cleaning_needed?
|
378
381
|
end
|
379
382
|
|
380
383
|
event :sleep do
|
381
|
-
transitions :
|
384
|
+
transitions from: :running, to: :sleeping, unless: :cleaning_needed?
|
382
385
|
end
|
383
386
|
end
|
384
387
|
```
|
385
388
|
|
389
|
+
You can invoke a Class instead a method since this Class responds to `call`
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
event :sleep do
|
393
|
+
transitions from: :running, to: :sleeping, guards: Dog
|
394
|
+
end
|
395
|
+
```
|
396
|
+
```ruby
|
397
|
+
class Dog
|
398
|
+
def call
|
399
|
+
cleaning_needed? && walked?
|
400
|
+
end
|
401
|
+
...
|
402
|
+
end
|
403
|
+
```
|
386
404
|
|
387
405
|
### Transitions
|
388
406
|
|
@@ -395,7 +413,7 @@ class Job
|
|
395
413
|
include AASM
|
396
414
|
|
397
415
|
aasm do
|
398
|
-
state :stage1, :
|
416
|
+
state :stage1, initial: true
|
399
417
|
state :stage2
|
400
418
|
state :stage3
|
401
419
|
state :completed
|
@@ -416,40 +434,59 @@ job.stage1_completed
|
|
416
434
|
job.aasm.current_state # stage3
|
417
435
|
```
|
418
436
|
|
437
|
+
### Display name for state
|
438
|
+
|
439
|
+
You can define display name for state using :display option
|
440
|
+
|
441
|
+
```ruby
|
442
|
+
class Job
|
443
|
+
include AASM
|
444
|
+
|
445
|
+
aasm do
|
446
|
+
state :stage1, initial: true, display: 'First Stage'
|
447
|
+
state :stage2
|
448
|
+
state :stage3
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
job = Job.new
|
453
|
+
job.aasm.human_state
|
454
|
+
|
455
|
+
```
|
419
456
|
|
420
457
|
### Multiple state machines per class
|
421
458
|
|
422
459
|
Multiple state machines per class are supported. Be aware though that _AASM_ has been
|
423
|
-
built with one state machine per class in mind. Nonetheless, here's how to do it
|
460
|
+
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.
|
424
461
|
|
425
462
|
```ruby
|
426
463
|
class SimpleMultipleExample
|
427
464
|
include AASM
|
428
|
-
aasm(:move) do
|
429
|
-
state :standing, :
|
465
|
+
aasm(:move, column: 'move_state') do
|
466
|
+
state :standing, initial: true
|
430
467
|
state :walking
|
431
468
|
state :running
|
432
469
|
|
433
470
|
event :walk do
|
434
|
-
transitions :
|
471
|
+
transitions from: :standing, to: :walking
|
435
472
|
end
|
436
473
|
event :run do
|
437
|
-
transitions :
|
474
|
+
transitions from: [:standing, :walking], to: :running
|
438
475
|
end
|
439
476
|
event :hold do
|
440
|
-
transitions :
|
477
|
+
transitions from: [:walking, :running], to: :standing
|
441
478
|
end
|
442
479
|
end
|
443
480
|
|
444
|
-
aasm(:work) do
|
445
|
-
state :sleeping, :
|
481
|
+
aasm(:work, column: 'work_state') do
|
482
|
+
state :sleeping, initial: true
|
446
483
|
state :processing
|
447
484
|
|
448
485
|
event :start do
|
449
|
-
transitions :
|
486
|
+
transitions from: :sleeping, to: :processing
|
450
487
|
end
|
451
488
|
event :stop do
|
452
|
-
transitions :
|
489
|
+
transitions from: :processing, to: :sleeping
|
453
490
|
end
|
454
491
|
end
|
455
492
|
end
|
@@ -482,28 +519,28 @@ Alternatively, you can provide a namespace for each state machine:
|
|
482
519
|
class NamespacedMultipleExample
|
483
520
|
include AASM
|
484
521
|
aasm(:status) do
|
485
|
-
state :unapproved, :
|
522
|
+
state :unapproved, initial: true
|
486
523
|
state :approved
|
487
524
|
|
488
525
|
event :approve do
|
489
|
-
transitions :
|
526
|
+
transitions from: :unapproved, to: :approved
|
490
527
|
end
|
491
528
|
|
492
529
|
event :unapprove do
|
493
|
-
transitions :
|
530
|
+
transitions from: :approved, to: :unapproved
|
494
531
|
end
|
495
532
|
end
|
496
533
|
|
497
534
|
aasm(:review_status, namespace: :review) do
|
498
|
-
state :unapproved, :
|
535
|
+
state :unapproved, initial: true
|
499
536
|
state :approved
|
500
537
|
|
501
538
|
event :approve do
|
502
|
-
transitions :
|
539
|
+
transitions from: :unapproved, to: :approved
|
503
540
|
end
|
504
541
|
|
505
542
|
event :unapprove do
|
506
|
-
transitions :
|
543
|
+
transitions from: :approved, to: :unapproved
|
507
544
|
end
|
508
545
|
end
|
509
546
|
end
|
@@ -523,7 +560,7 @@ All _AASM_ class- and instance-level `aasm` methods accept a state machine selec
|
|
523
560
|
So, for example, to use inspection on a class level, you have to use
|
524
561
|
|
525
562
|
```ruby
|
526
|
-
SimpleMultipleExample.aasm(:
|
563
|
+
SimpleMultipleExample.aasm(:move).states.map(&:name)
|
527
564
|
# => [:standing, :walking, :running]
|
528
565
|
```
|
529
566
|
|
@@ -535,26 +572,26 @@ class Example
|
|
535
572
|
include AASM
|
536
573
|
|
537
574
|
aasm(:work) do
|
538
|
-
state :sleeping, :
|
575
|
+
state :sleeping, initial: true
|
539
576
|
state :processing
|
540
577
|
|
541
578
|
event :start do
|
542
|
-
transitions :
|
579
|
+
transitions from: :sleeping, to: :processing
|
543
580
|
end
|
544
581
|
event :stop do
|
545
|
-
transitions :
|
582
|
+
transitions from: :processing, to: :sleeping
|
546
583
|
end
|
547
584
|
end
|
548
585
|
|
549
586
|
aasm(:question) do
|
550
|
-
state :answered, :
|
587
|
+
state :answered, initial: true
|
551
588
|
state :asked
|
552
589
|
|
553
|
-
event :ask, :
|
554
|
-
transitions :
|
590
|
+
event :ask, binding_event: :start do
|
591
|
+
transitions from: :answered, to: :asked
|
555
592
|
end
|
556
|
-
event :answer, :
|
557
|
-
transitions :
|
593
|
+
event :answer, binding_event: :stop do
|
594
|
+
transitions from: :asked, to: :answered
|
558
595
|
end
|
559
596
|
end
|
560
597
|
end
|
@@ -600,7 +637,7 @@ class CustomAASMBase < AASM::Base
|
|
600
637
|
# A custom transiton that we want available across many AASM models.
|
601
638
|
def count_transitions!
|
602
639
|
klass.class_eval do
|
603
|
-
aasm :
|
640
|
+
aasm with_klass: CustomAASMBase do
|
604
641
|
after_all_transitions :increment_transition_count
|
605
642
|
end
|
606
643
|
end
|
@@ -630,26 +667,26 @@ class CustomAASMBase < AASM::Base
|
|
630
667
|
end
|
631
668
|
```
|
632
669
|
|
633
|
-
When we declare our model that has an AASM state machine, we simply declare the AASM block with a `:
|
670
|
+
When we declare our model that has an AASM state machine, we simply declare the AASM block with a `:with_klass` key to our own class.
|
634
671
|
|
635
672
|
```ruby
|
636
673
|
class SimpleCustomExample
|
637
674
|
include AASM
|
638
675
|
|
639
676
|
# Let's build an AASM state machine with our custom class.
|
640
|
-
aasm :
|
677
|
+
aasm with_klass: CustomAASMBase do
|
641
678
|
requires_guards!
|
642
679
|
count_transitions!
|
643
680
|
|
644
|
-
state :initialised, :
|
681
|
+
state :initialised, initial: true
|
645
682
|
state :filled_out
|
646
683
|
state :authorised
|
647
684
|
|
648
685
|
event :fill_out do
|
649
|
-
transitions :
|
686
|
+
transitions from: :initialised, to: :filled_out, guard: :fillable?
|
650
687
|
end
|
651
688
|
event :authorise do
|
652
|
-
transitions :
|
689
|
+
transitions from: :filled_out, to: :authorised, guard: :authorizable?
|
653
690
|
end
|
654
691
|
end
|
655
692
|
end
|
@@ -661,20 +698,22 @@ end
|
|
661
698
|
AASM comes with support for ActiveRecord and allows automatic persisting of the object's
|
662
699
|
state in the database.
|
663
700
|
|
701
|
+
Add `gem 'after_commit_everywhere', '~> 0.1', '>= 0.1.5'` to your Gemfile
|
702
|
+
|
664
703
|
```ruby
|
665
704
|
class Job < ActiveRecord::Base
|
666
705
|
include AASM
|
667
706
|
|
668
707
|
aasm do # default column: aasm_state
|
669
|
-
state :sleeping, :
|
708
|
+
state :sleeping, initial: true
|
670
709
|
state :running
|
671
710
|
|
672
711
|
event :run do
|
673
|
-
transitions :
|
712
|
+
transitions from: :sleeping, to: :running
|
674
713
|
end
|
675
714
|
|
676
715
|
event :sleep do
|
677
|
-
transitions :
|
716
|
+
transitions from: :running, to: :sleeping
|
678
717
|
end
|
679
718
|
end
|
680
719
|
|
@@ -709,22 +748,30 @@ be updated in the database (just like ActiveRecord `update_column` is working).
|
|
709
748
|
class Job < ActiveRecord::Base
|
710
749
|
include AASM
|
711
750
|
|
712
|
-
aasm :
|
713
|
-
state :sleeping, :
|
751
|
+
aasm skip_validation_on_save: true do
|
752
|
+
state :sleeping, initial: true
|
714
753
|
state :running
|
715
754
|
|
716
755
|
event :run do
|
717
|
-
transitions :
|
756
|
+
transitions from: :sleeping, to: :running
|
718
757
|
end
|
719
758
|
|
720
759
|
event :sleep do
|
721
|
-
transitions :
|
760
|
+
transitions from: :running, to: :sleeping
|
722
761
|
end
|
723
762
|
end
|
724
763
|
|
725
764
|
end
|
726
765
|
```
|
727
766
|
|
767
|
+
Also You can skip the validation at instance level with `some_event_name_without_validation!` method.
|
768
|
+
With this you have the flexibility of having validation for all your transitions by default and then skip it wherever required.
|
769
|
+
Please note that only state column will be updated as mentioned in the above example.
|
770
|
+
|
771
|
+
```ruby
|
772
|
+
job.run_without_validation!
|
773
|
+
```
|
774
|
+
|
728
775
|
If you want to make sure that the _AASM_ column for storing the state is not directly assigned,
|
729
776
|
configure _AASM_ to not allow direct assignment, like this:
|
730
777
|
|
@@ -732,12 +779,12 @@ configure _AASM_ to not allow direct assignment, like this:
|
|
732
779
|
class Job < ActiveRecord::Base
|
733
780
|
include AASM
|
734
781
|
|
735
|
-
aasm :
|
736
|
-
state :sleeping, :
|
782
|
+
aasm no_direct_assignment: true do
|
783
|
+
state :sleeping, initial: true
|
737
784
|
state :running
|
738
785
|
|
739
786
|
event :run do
|
740
|
-
transitions :
|
787
|
+
transitions from: :sleeping, to: :running
|
741
788
|
end
|
742
789
|
end
|
743
790
|
|
@@ -768,8 +815,8 @@ class Job < ActiveRecord::Base
|
|
768
815
|
running: 99
|
769
816
|
}
|
770
817
|
|
771
|
-
aasm :
|
772
|
-
state :sleeping, :
|
818
|
+
aasm column: :state, enum: true do
|
819
|
+
state :sleeping, initial: true
|
773
820
|
state :running
|
774
821
|
end
|
775
822
|
end
|
@@ -825,6 +872,23 @@ class Job
|
|
825
872
|
end
|
826
873
|
```
|
827
874
|
|
875
|
+
### NoBrainer
|
876
|
+
|
877
|
+
AASM also supports persistence to [RethinkDB](https://www.rethinkdb.com/)
|
878
|
+
if you're using [Nobrainer](http://nobrainer.io/).
|
879
|
+
Make sure to include NoBrainer::Document before you include AASM.
|
880
|
+
|
881
|
+
```ruby
|
882
|
+
class Job
|
883
|
+
include NoBrainer::Document
|
884
|
+
include AASM
|
885
|
+
field :aasm_state
|
886
|
+
aasm do
|
887
|
+
...
|
888
|
+
end
|
889
|
+
end
|
890
|
+
```
|
891
|
+
|
828
892
|
### Redis
|
829
893
|
|
830
894
|
AASM also supports persistence in Redis via
|
@@ -851,7 +915,7 @@ class Job < ActiveRecord::Base
|
|
851
915
|
include AASM
|
852
916
|
|
853
917
|
aasm do
|
854
|
-
state :sleeping, :
|
918
|
+
state :sleeping, initial: true
|
855
919
|
state :running
|
856
920
|
state :cleaning
|
857
921
|
end
|
@@ -880,8 +944,8 @@ defining the `AASM` states, like this:
|
|
880
944
|
class Job < ActiveRecord::Base
|
881
945
|
include AASM
|
882
946
|
|
883
|
-
aasm :
|
884
|
-
state :sleeping, :
|
947
|
+
aasm create_scopes: false do
|
948
|
+
state :sleeping, initial: true
|
885
949
|
state :running
|
886
950
|
state :cleaning
|
887
951
|
end
|
@@ -914,11 +978,11 @@ class Job < ActiveRecord::Base
|
|
914
978
|
include AASM
|
915
979
|
|
916
980
|
aasm do
|
917
|
-
state :sleeping, :
|
981
|
+
state :sleeping, initial: true
|
918
982
|
state :running
|
919
983
|
|
920
|
-
event :run, :
|
921
|
-
transitions :
|
984
|
+
event :run, after_commit: :notify_about_running_job do
|
985
|
+
transitions from: :sleeping, to: :running
|
922
986
|
end
|
923
987
|
end
|
924
988
|
|
@@ -940,18 +1004,24 @@ job.run
|
|
940
1004
|
job.save! #notify_about_running_job is not run
|
941
1005
|
```
|
942
1006
|
|
1007
|
+
Please note that `:after_commit` AASM callbacks behaves around custom implementation
|
1008
|
+
of transaction pattern rather than a real-life DB transaction. This fact still causes
|
1009
|
+
the race conditions and redundant callback calls within nested transaction. In order
|
1010
|
+
to fix that it's highly recommended to add `gem 'after_commit_everywhere', '~> 0.1', '>= 0.1.5'`
|
1011
|
+
to your `Gemfile`.
|
1012
|
+
|
943
1013
|
If you want to encapsulate state changes within an own transaction, the behavior
|
944
1014
|
of this nested transaction might be confusing. Take a look at
|
945
1015
|
[ActiveRecord Nested Transactions](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)
|
946
1016
|
if you want to know more about this. Nevertheless, AASM by default requires a new transaction
|
947
|
-
`transaction(:
|
1017
|
+
`transaction(requires_new: true)`. You can override this behavior by changing
|
948
1018
|
the configuration
|
949
1019
|
|
950
1020
|
```ruby
|
951
1021
|
class Job < ActiveRecord::Base
|
952
1022
|
include AASM
|
953
1023
|
|
954
|
-
aasm :
|
1024
|
+
aasm requires_new_transaction: false do
|
955
1025
|
...
|
956
1026
|
end
|
957
1027
|
|
@@ -959,7 +1029,7 @@ class Job < ActiveRecord::Base
|
|
959
1029
|
end
|
960
1030
|
```
|
961
1031
|
|
962
|
-
which then leads to `transaction(:
|
1032
|
+
which then leads to `transaction(requires_new: false)`, the Rails default.
|
963
1033
|
|
964
1034
|
Additionally, if you do not want any of your active record actions to be
|
965
1035
|
wrapped in a transaction, you can specify the `use_transactions` flag. This can
|
@@ -971,7 +1041,7 @@ result of a transaction or callback, even when some error occurs. The
|
|
971
1041
|
class Job < ActiveRecord::Base
|
972
1042
|
include AASM
|
973
1043
|
|
974
|
-
aasm :
|
1044
|
+
aasm use_transactions: false do
|
975
1045
|
...
|
976
1046
|
end
|
977
1047
|
|
@@ -994,7 +1064,7 @@ AASM supports [Active Record pessimistic locking via `with_lock`](http://api.rub
|
|
994
1064
|
class Job < ActiveRecord::Base
|
995
1065
|
include AASM
|
996
1066
|
|
997
|
-
aasm :
|
1067
|
+
aasm requires_lock: true do
|
998
1068
|
...
|
999
1069
|
end
|
1000
1070
|
|
@@ -1006,7 +1076,7 @@ end
|
|
1006
1076
|
class Job < ActiveRecord::Base
|
1007
1077
|
include AASM
|
1008
1078
|
|
1009
|
-
aasm :
|
1079
|
+
aasm requires_lock: 'FOR UPDATE NOWAIT' do
|
1010
1080
|
...
|
1011
1081
|
end
|
1012
1082
|
|
@@ -1024,18 +1094,21 @@ this by defining your favorite column name, using `:column` like this:
|
|
1024
1094
|
class Job < ActiveRecord::Base
|
1025
1095
|
include AASM
|
1026
1096
|
|
1027
|
-
aasm :
|
1097
|
+
aasm column: :my_state do
|
1028
1098
|
...
|
1029
1099
|
end
|
1030
1100
|
|
1031
|
-
aasm :another_state_machine, column:
|
1101
|
+
aasm :another_state_machine, column: :second_state do
|
1032
1102
|
...
|
1033
1103
|
end
|
1034
1104
|
end
|
1035
1105
|
```
|
1036
1106
|
|
1037
1107
|
Whatever column name is used, make sure to add a migration to provide this column
|
1038
|
-
(of type `string`)
|
1108
|
+
(of type `string`).
|
1109
|
+
Do not add default value for column at the database level. If you add default
|
1110
|
+
value in database then AASM callbacks on the initial state will not be fired upon
|
1111
|
+
instantiation of the model.
|
1039
1112
|
|
1040
1113
|
```ruby
|
1041
1114
|
class AddJobState < ActiveRecord::Migration
|
@@ -1049,6 +1122,13 @@ class AddJobState < ActiveRecord::Migration
|
|
1049
1122
|
end
|
1050
1123
|
```
|
1051
1124
|
|
1125
|
+
### Log State Changes
|
1126
|
+
|
1127
|
+
Logging state change can be done using [paper_trail](https://github.com/paper-trail-gem/paper_trail) gem
|
1128
|
+
|
1129
|
+
Example of implementation can be found here [https://github.com/nitsujri/aasm-papertrail-example](https://github.com/nitsujri/aasm-papertrail-example)
|
1130
|
+
|
1131
|
+
|
1052
1132
|
### Inspection
|
1053
1133
|
|
1054
1134
|
AASM supports query methods for states and events
|
@@ -1060,19 +1140,19 @@ class Job
|
|
1060
1140
|
include AASM
|
1061
1141
|
|
1062
1142
|
aasm do
|
1063
|
-
state :sleeping, :
|
1143
|
+
state :sleeping, initial: true
|
1064
1144
|
state :running, :cleaning
|
1065
1145
|
|
1066
1146
|
event :run do
|
1067
|
-
transitions :
|
1147
|
+
transitions from: :sleeping, to: :running
|
1068
1148
|
end
|
1069
1149
|
|
1070
1150
|
event :clean do
|
1071
|
-
transitions :
|
1151
|
+
transitions from: :running, to: :cleaning, guard: :cleaning_needed?
|
1072
1152
|
end
|
1073
1153
|
|
1074
1154
|
event :sleep do
|
1075
|
-
transitions :
|
1155
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
1076
1156
|
end
|
1077
1157
|
end
|
1078
1158
|
|
@@ -1090,15 +1170,19 @@ Job.aasm.states.map(&:name)
|
|
1090
1170
|
job = Job.new
|
1091
1171
|
|
1092
1172
|
# show all permitted states (from initial state)
|
1093
|
-
job.aasm.states(:
|
1173
|
+
job.aasm.states(permitted: true).map(&:name)
|
1094
1174
|
#=> [:running]
|
1095
1175
|
|
1176
|
+
# List all the permitted transitions(event and state pairs) from initial state
|
1177
|
+
job.aasm.permitted_transitions
|
1178
|
+
#=> [{ :event => :run, :state => :running }]
|
1179
|
+
|
1096
1180
|
job.run
|
1097
|
-
job.aasm.states(:
|
1181
|
+
job.aasm.states(permitted: true).map(&:name)
|
1098
1182
|
#=> [:sleeping]
|
1099
1183
|
|
1100
1184
|
# show all non permitted states
|
1101
|
-
job.aasm.states(:
|
1185
|
+
job.aasm.states(permitted: false).map(&:name)
|
1102
1186
|
#=> [:cleaning]
|
1103
1187
|
|
1104
1188
|
# show all possible (triggerable) events from the current state
|
@@ -1106,23 +1190,23 @@ job.aasm.events.map(&:name)
|
|
1106
1190
|
#=> [:clean, :sleep]
|
1107
1191
|
|
1108
1192
|
# show all permitted events
|
1109
|
-
job.aasm.events(:
|
1193
|
+
job.aasm.events(permitted: true).map(&:name)
|
1110
1194
|
#=> [:sleep]
|
1111
1195
|
|
1112
1196
|
# show all non permitted events
|
1113
|
-
job.aasm.events(:
|
1197
|
+
job.aasm.events(permitted: false).map(&:name)
|
1114
1198
|
#=> [:clean]
|
1115
1199
|
|
1116
1200
|
# show all possible events except a specific one
|
1117
|
-
job.aasm.events(:
|
1201
|
+
job.aasm.events(reject: :sleep).map(&:name)
|
1118
1202
|
#=> [:clean]
|
1119
1203
|
|
1120
1204
|
# list states for select
|
1121
1205
|
Job.aasm.states_for_select
|
1122
|
-
|
1206
|
+
#=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
|
1123
1207
|
|
1124
1208
|
# show permitted states with guard parameter
|
1125
|
-
job.aasm.states({:
|
1209
|
+
job.aasm.states({permitted: true}, guard_parameter).map(&:name)
|
1126
1210
|
```
|
1127
1211
|
|
1128
1212
|
|
@@ -1135,7 +1219,7 @@ use
|
|
1135
1219
|
class Job
|
1136
1220
|
include AASM
|
1137
1221
|
|
1138
|
-
aasm :
|
1222
|
+
aasm logger: Rails.logger do
|
1139
1223
|
...
|
1140
1224
|
end
|
1141
1225
|
end
|
@@ -1159,7 +1243,15 @@ the 'instance method symbol / string' way whenever possible when defining guardi
|
|
1159
1243
|
|
1160
1244
|
#### RSpec
|
1161
1245
|
|
1162
|
-
AASM provides some matchers for [RSpec](http://rspec.info):
|
1246
|
+
AASM provides some matchers for [RSpec](http://rspec.info):
|
1247
|
+
* `transition_from`,
|
1248
|
+
* `have_state`, `allow_event`
|
1249
|
+
* and `allow_transition_to`.
|
1250
|
+
|
1251
|
+
##### Installation Instructions:
|
1252
|
+
* Add `require 'aasm/rspec'` to your `spec_helper.rb` file.
|
1253
|
+
|
1254
|
+
##### Examples Of Usage in Rspec:
|
1163
1255
|
|
1164
1256
|
```ruby
|
1165
1257
|
# classes with only the default state machine
|
@@ -1172,7 +1264,7 @@ expect(job).to allow_event :run
|
|
1172
1264
|
expect(job).to_not allow_event :clean
|
1173
1265
|
expect(job).to allow_transition_to(:running)
|
1174
1266
|
expect(job).to_not allow_transition_to(:cleaning)
|
1175
|
-
# on_event also accept arguments
|
1267
|
+
# on_event also accept multiple arguments
|
1176
1268
|
expect(job).to transition_from(:sleeping).to(:running).on_event(:run, :defragmentation)
|
1177
1269
|
|
1178
1270
|
# classes with multiple state machine
|
@@ -1193,6 +1285,9 @@ expect(multiple).to allow_event(:start).on(:move)
|
|
1193
1285
|
expect(multiple).to_not allow_event(:stop).on(:move)
|
1194
1286
|
expect(multiple).to allow_transition_to(:processing).on(:move)
|
1195
1287
|
expect(multiple).to_not allow_transition_to(:sleeping).on(:move)
|
1288
|
+
# allow_event also accepts arguments
|
1289
|
+
expect(job).to allow_event(:run).with(:defragmentation)
|
1290
|
+
|
1196
1291
|
```
|
1197
1292
|
|
1198
1293
|
#### Minitest
|
@@ -1203,7 +1298,10 @@ AASM provides assertions and rspec-like expectations for [Minitest](https://gith
|
|
1203
1298
|
|
1204
1299
|
List of supported assertions: `assert_have_state`, `refute_have_state`, `assert_transitions_from`, `refute_transitions_from`, `assert_event_allowed`, `refute_event_allowed`, `assert_transition_to_allowed`, `refute_transition_to_allowed`.
|
1205
1300
|
|
1206
|
-
|
1301
|
+
|
1302
|
+
##### Examples Of Usage (Minitest):
|
1303
|
+
|
1304
|
+
Add `require 'aasm/minitest'` to your `test_helper.rb` file and use them like this:
|
1207
1305
|
|
1208
1306
|
```ruby
|
1209
1307
|
# classes with only the default state machine
|
@@ -1312,6 +1410,14 @@ Replace NAME with the Model name, COLUMN_NAME is optional(default is 'aasm_state
|
|
1312
1410
|
This will create a model (if one does not exist) and configure it with aasm block.
|
1313
1411
|
For Active record orm a migration file is added to add aasm state column to table.
|
1314
1412
|
|
1413
|
+
### Docker
|
1414
|
+
|
1415
|
+
Run test suite easily on docker
|
1416
|
+
```
|
1417
|
+
1. docker-compose build aasm
|
1418
|
+
2. docker-compose run --rm aasm
|
1419
|
+
```
|
1420
|
+
|
1315
1421
|
## Latest changes ##
|
1316
1422
|
|
1317
1423
|
Take a look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details about recent changes to the current version.
|