aasm 4.12.3 → 5.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. data/.travis.yml +48 -18
  5. data/Appraisals +50 -26
  6. data/CHANGELOG.md +75 -3
  7. data/Dockerfile +44 -0
  8. data/Gemfile +2 -3
  9. data/README.md +216 -110
  10. data/aasm.gemspec +2 -0
  11. data/docker-compose.yml +40 -0
  12. data/gemfiles/norails.gemfile +10 -0
  13. data/gemfiles/rails_4.2.gemfile +9 -8
  14. data/gemfiles/rails_4.2_mongoid_5.gemfile +6 -5
  15. data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
  16. data/gemfiles/rails_5.0.gemfile +6 -6
  17. data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
  18. data/gemfiles/rails_5.1.gemfile +14 -0
  19. data/gemfiles/rails_5.2.gemfile +14 -0
  20. data/lib/aasm.rb +5 -2
  21. data/lib/aasm/aasm.rb +30 -27
  22. data/lib/aasm/base.rb +25 -7
  23. data/lib/aasm/core/event.rb +14 -24
  24. data/lib/aasm/core/invoker.rb +129 -0
  25. data/lib/aasm/core/invokers/base_invoker.rb +75 -0
  26. data/lib/aasm/core/invokers/class_invoker.rb +52 -0
  27. data/lib/aasm/core/invokers/literal_invoker.rb +47 -0
  28. data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
  29. data/lib/aasm/core/state.rb +10 -9
  30. data/lib/aasm/core/transition.rb +7 -68
  31. data/lib/aasm/errors.rb +4 -3
  32. data/lib/aasm/instance_base.rb +16 -4
  33. data/lib/aasm/persistence.rb +3 -0
  34. data/lib/aasm/persistence/active_record_persistence.rb +25 -5
  35. data/lib/aasm/persistence/base.rb +1 -1
  36. data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
  37. data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
  38. data/lib/aasm/persistence/mongoid_persistence.rb +1 -1
  39. data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
  40. data/lib/aasm/persistence/orm.rb +23 -19
  41. data/lib/aasm/persistence/plain_persistence.rb +2 -1
  42. data/lib/aasm/persistence/redis_persistence.rb +1 -1
  43. data/lib/aasm/persistence/sequel_persistence.rb +0 -1
  44. data/lib/aasm/rspec/allow_event.rb +5 -1
  45. data/lib/aasm/rspec/allow_transition_to.rb +5 -1
  46. data/lib/aasm/rspec/transition_from.rb +5 -1
  47. data/lib/aasm/version.rb +1 -1
  48. data/lib/generators/aasm/orm_helpers.rb +6 -0
  49. data/lib/generators/active_record/aasm_generator.rb +3 -1
  50. data/lib/generators/nobrainer/aasm_generator.rb +28 -0
  51. data/lib/motion-aasm.rb +1 -0
  52. data/spec/database.rb +16 -1
  53. data/spec/en.yml +0 -3
  54. data/spec/generators/active_record_generator_spec.rb +6 -0
  55. data/spec/generators/no_brainer_generator_spec.rb +29 -0
  56. data/spec/{en_deprecated_style.yml → localizer_test_model_deprecated_style.yml} +0 -4
  57. data/spec/localizer_test_model_new_style.yml +5 -0
  58. data/spec/models/active_record/active_record_callback.rb +93 -0
  59. data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
  60. data/spec/models/active_record/localizer_test_model.rb +3 -3
  61. data/spec/models/active_record/person.rb +23 -0
  62. data/spec/models/active_record/simple_new_dsl.rb +15 -0
  63. data/spec/models/active_record/work.rb +3 -0
  64. data/spec/models/callbacks/with_state_arg.rb +5 -1
  65. data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
  66. data/spec/models/default_state.rb +1 -1
  67. data/spec/models/nobrainer/complex_no_brainer_example.rb +36 -0
  68. data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +39 -0
  69. data/spec/models/nobrainer/no_scope_no_brainer.rb +21 -0
  70. data/spec/models/nobrainer/nobrainer_relationships.rb +25 -0
  71. data/spec/models/nobrainer/silent_persistor_no_brainer.rb +39 -0
  72. data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +25 -0
  73. data/spec/models/nobrainer/simple_no_brainer.rb +23 -0
  74. data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
  75. data/spec/models/simple_example.rb +8 -0
  76. data/spec/models/simple_example_with_guard_args.rb +17 -0
  77. data/spec/spec_helper.rb +15 -0
  78. data/spec/spec_helpers/active_record.rb +2 -1
  79. data/spec/spec_helpers/dynamoid.rb +7 -5
  80. data/spec/spec_helpers/mongoid.rb +20 -1
  81. data/spec/spec_helpers/nobrainer.rb +15 -0
  82. data/spec/spec_helpers/redis.rb +5 -2
  83. data/spec/spec_helpers/sequel.rb +1 -1
  84. data/spec/unit/abstract_class_spec.rb +27 -0
  85. data/spec/unit/api_spec.rb +4 -0
  86. data/spec/unit/callback_multiple_spec.rb +7 -3
  87. data/spec/unit/callbacks_spec.rb +32 -2
  88. data/spec/unit/complex_example_spec.rb +0 -1
  89. data/spec/unit/event_spec.rb +13 -0
  90. data/spec/unit/exception_spec.rb +1 -1
  91. data/spec/unit/inspection_multiple_spec.rb +9 -5
  92. data/spec/unit/inspection_spec.rb +7 -3
  93. data/spec/unit/invoker_spec.rb +189 -0
  94. data/spec/unit/invokers/base_invoker_spec.rb +72 -0
  95. data/spec/unit/invokers/class_invoker_spec.rb +95 -0
  96. data/spec/unit/invokers/literal_invoker_spec.rb +86 -0
  97. data/spec/unit/invokers/proc_invoker_spec.rb +86 -0
  98. data/spec/unit/localizer_spec.rb +9 -10
  99. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +4 -4
  100. data/spec/unit/persistence/active_record_persistence_spec.rb +109 -4
  101. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -4
  102. data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -4
  103. data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +198 -0
  104. data/spec/unit/persistence/no_brainer_persistence_spec.rb +158 -0
  105. data/spec/unit/rspec_matcher_spec.rb +9 -0
  106. data/spec/unit/simple_example_spec.rb +15 -0
  107. data/spec/unit/state_spec.rb +23 -7
  108. data/spec/unit/transition_spec.rb +1 -1
  109. data/test/minitest_helper.rb +2 -2
  110. data/test/unit/minitest_matcher_test.rb +1 -1
  111. metadata +106 -12
  112. data/callbacks.txt +0 -51
  113. data/gemfiles/rails_3.2.gemfile +0 -13
  114. data/gemfiles/rails_4.0.gemfile +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 485dd737c1e66c6abf9ad6beec5b88610e282cf5
4
- data.tar.gz: dc4e4de44fbb182924bc28b13aff6708766f2cfc
2
+ SHA256:
3
+ metadata.gz: f2f4099a66f8d753c2bd7c06b3c378dcd37b47acf9b2f7487784e7762742c1c4
4
+ data.tar.gz: 8971b36f1b066c08d3a4d278a99d7c1e5386be72182da62b51a82db1e60e9e9f
5
5
  SHA512:
6
- metadata.gz: 8211acf5c307b6c04b04ff0aad09aecece63d8df1fc6dbe3de14e363ab415a1e0291510b2d4783cf9cd22391415a25e4ac72d7f43f35ea612b60f939ab6def2a
7
- data.tar.gz: a95bd160171a94dfc8ac1a4de0594372c336cf546f38727cacc95ca73af43369419bc6b3637634faa02b7eae6b8c668d29c5b74a5eb930aba4a03af190f8364a
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
- - 1.9.3
7
- - 2.2.6
8
- - 2.3.3
9
- - jruby-1.7 # JRuby in 1.9 mode
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/rails_3.2.gemfile
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: 1.9.3
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: 1.9.3
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: jruby-1.7
46
- gemfile: gemfiles/rails_5.0.gemfile
47
- - rvm: jruby-9.0.5.0
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 'rails_3.2' do
2
- gem 'rails', '~>3.2.22'
3
- gem 'mongoid', '~>3.1'
4
- gem 'sequel'
5
- gem 'bson_ext', :platforms => :ruby
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', :platforms => :ruby
15
- gem 'aws-sdk', '~>2', :platforms => :ruby
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.2' do
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 'mongoid', '~>4.0'
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', :platforms => [:ruby_19, :jruby]
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', '~> 1', :platforms => :ruby
41
- gem 'aws-sdk', '~>2', :platforms => :ruby
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] (https://github.com/Aryk)
18
- * Add aliases for event methods [#476](https://github.com/aasm/aasm/pull/476), thanks to [@Aryk] (https://github.com/Aryk)
19
- * Support Minitest spec expectations [#387](https://github.com/aasm/aasm/pull/387), thanks to [@faragorn] (https://github.com/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
@@ -2,6 +2,5 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'sqlite3', :platforms => :ruby
6
- gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby
7
- gem 'rails', '5.1.3'
5
+ gem 'sqlite3', '~> 1.3.5', :platforms => :ruby
6
+ gem 'rails', '5.1.4'
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
- [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html),
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, :initial => true
75
+ state :sleeping, initial: true
75
76
  state :running, :cleaning
76
77
 
77
78
  event :run do
78
- transitions :from => :sleeping, :to => :running
79
+ transitions from: :sleeping, to: :running
79
80
  end
80
81
 
81
82
  event :clean do
82
- transitions :from => :running, :to => :cleaning
83
+ transitions from: :running, to: :cleaning
83
84
  end
84
85
 
85
86
  event :sleep do
86
- transitions :from => [:running, :cleaning], :to => :sleeping
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 :whiny_transitions => false do
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, when certain criteria are met, like entering a particular state:
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, :initial => true, :before_enter => :do_something
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, :after => :notify_somebody do
148
+ event :run, after: :notify_somebody do
148
149
  before do
149
150
  log('Preparing to run')
150
151
  end
151
152
 
152
- transitions :from => :sleeping, :to => :running, :after => Proc.new {|*args| set_process(*args) }
153
- transitions :from => :running, :to => :finished, :after => LogRunTime
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 :from => :running, :to => :sleeping
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(:running, :defragmentation)
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, :initial => true
317
+ state :idle, initial: true
315
318
  state :cleaning
316
319
 
317
320
  event :clean do
318
- transitions :from => :idle, :to => :cleaning, :guard => :cleaning_needed?
321
+ transitions from: :idle, to: :cleaning, guard: :cleaning_needed?
319
322
  end
320
323
 
321
324
  event :clean_if_needed do
322
- transitions :from => :idle, :to => :cleaning do
325
+ transitions from: :idle, to: :cleaning do
323
326
  guard do
324
327
  cleaning_needed?
325
328
  end
326
329
  end
327
- transitions :from => :idle, :to => :idle
330
+ transitions from: :idle, to: :idle
328
331
  end
329
332
 
330
333
  event :clean_if_dirty do
331
- transitions :from => :idle, :to => :cleaning, :guard => :if_dirty?
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 :from => :running, :to => :sleeping, :guards => [:cleaning_needed?, :walked_the_dog?]
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, :guards => [:walked_the_dog?] do
368
- transitions :from => :running, :to => :sleeping, :guards => [:cleaning_needed?]
369
- transitions :from => :cleaning, :to => :sleeping
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 :from => :running, :to => :cleaning, :if => :cleaning_needed?
380
+ transitions from: :running, to: :cleaning, if: :cleaning_needed?
378
381
  end
379
382
 
380
383
  event :sleep do
381
- transitions :from => :running, :to => :sleeping, :unless => :cleaning_needed?
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, :initial => true
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, :initial => true
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 :from => :standing, :to => :walking
471
+ transitions from: :standing, to: :walking
435
472
  end
436
473
  event :run do
437
- transitions :from => [:standing, :walking], :to => :running
474
+ transitions from: [:standing, :walking], to: :running
438
475
  end
439
476
  event :hold do
440
- transitions :from => [:walking, :running], :to => :standing
477
+ transitions from: [:walking, :running], to: :standing
441
478
  end
442
479
  end
443
480
 
444
- aasm(:work) do
445
- state :sleeping, :initial => true
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 :from => :sleeping, :to => :processing
486
+ transitions from: :sleeping, to: :processing
450
487
  end
451
488
  event :stop do
452
- transitions :from => :processing, :to => :sleeping
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, :initial => true
522
+ state :unapproved, initial: true
486
523
  state :approved
487
524
 
488
525
  event :approve do
489
- transitions :from => :unapproved, :to => :approved
526
+ transitions from: :unapproved, to: :approved
490
527
  end
491
528
 
492
529
  event :unapprove do
493
- transitions :from => :approved, :to => :unapproved
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, :initial => true
535
+ state :unapproved, initial: true
499
536
  state :approved
500
537
 
501
538
  event :approve do
502
- transitions :from => :unapproved, :to => :approved
539
+ transitions from: :unapproved, to: :approved
503
540
  end
504
541
 
505
542
  event :unapprove do
506
- transitions :from => :approved, :to => :unapproved
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(:work).states
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, :initial => true
575
+ state :sleeping, initial: true
539
576
  state :processing
540
577
 
541
578
  event :start do
542
- transitions :from => :sleeping, :to => :processing
579
+ transitions from: :sleeping, to: :processing
543
580
  end
544
581
  event :stop do
545
- transitions :from => :processing, :to => :sleeping
582
+ transitions from: :processing, to: :sleeping
546
583
  end
547
584
  end
548
585
 
549
586
  aasm(:question) do
550
- state :answered, :initial => true
587
+ state :answered, initial: true
551
588
  state :asked
552
589
 
553
- event :ask, :binding_event => :start do
554
- transitions :from => :answered, :to => :asked
590
+ event :ask, binding_event: :start do
591
+ transitions from: :answered, to: :asked
555
592
  end
556
- event :answer, :binding_event => :stop do
557
- transitions :from => :asked, :to => :answered
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 :with_klass => CustomAASMBase do
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 `:with` key to our own class.
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 :with_klass => CustomAASMBase do
677
+ aasm with_klass: CustomAASMBase do
641
678
  requires_guards!
642
679
  count_transitions!
643
680
 
644
- state :initialised, :initial => true
681
+ state :initialised, initial: true
645
682
  state :filled_out
646
683
  state :authorised
647
684
 
648
685
  event :fill_out do
649
- transitions :from => :initialised, :to => :filled_out, :guard => :fillable?
686
+ transitions from: :initialised, to: :filled_out, guard: :fillable?
650
687
  end
651
688
  event :authorise do
652
- transitions :from => :filled_out, :to => :authorised, :guard => :authorizable?
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, :initial => true
708
+ state :sleeping, initial: true
670
709
  state :running
671
710
 
672
711
  event :run do
673
- transitions :from => :sleeping, :to => :running
712
+ transitions from: :sleeping, to: :running
674
713
  end
675
714
 
676
715
  event :sleep do
677
- transitions :from => :running, :to => :sleeping
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 :skip_validation_on_save => true do
713
- state :sleeping, :initial => true
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 :from => :sleeping, :to => :running
756
+ transitions from: :sleeping, to: :running
718
757
  end
719
758
 
720
759
  event :sleep do
721
- transitions :from => :running, :to => :sleeping
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 :no_direct_assignment => true do
736
- state :sleeping, :initial => true
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 :from => :sleeping, :to => :running
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 :column => :state, :enum => true do
772
- state :sleeping, :initial => true
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, :initial => true
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 :create_scopes => false do
884
- state :sleeping, :initial => true
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, :initial => true
981
+ state :sleeping, initial: true
918
982
  state :running
919
983
 
920
- event :run, :after_commit => :notify_about_running_job do
921
- transitions :from => :sleeping, :to => :running
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(:requires_new => true)`. You can override this behavior by changing
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 :requires_new_transaction => false do
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(:requires_new => false)`, the Rails default.
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 :use_transactions => false do
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 :requires_lock => true do
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 :requires_lock => 'FOR UPDATE NOWAIT' do
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 :column => 'my_state' do
1097
+ aasm column: :my_state do
1028
1098
  ...
1029
1099
  end
1030
1100
 
1031
- aasm :another_state_machine, column: 'second_state' do
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, :initial => true
1143
+ state :sleeping, initial: true
1064
1144
  state :running, :cleaning
1065
1145
 
1066
1146
  event :run do
1067
- transitions :from => :sleeping, :to => :running
1147
+ transitions from: :sleeping, to: :running
1068
1148
  end
1069
1149
 
1070
1150
  event :clean do
1071
- transitions :from => :running, :to => :cleaning, :guard => :cleaning_needed?
1151
+ transitions from: :running, to: :cleaning, guard: :cleaning_needed?
1072
1152
  end
1073
1153
 
1074
1154
  event :sleep do
1075
- transitions :from => [:running, :cleaning], :to => :sleeping
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(:permitted => true).map(&:name)
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(:permitted => true).map(&:name)
1181
+ job.aasm.states(permitted: true).map(&:name)
1098
1182
  #=> [:sleeping]
1099
1183
 
1100
1184
  # show all non permitted states
1101
- job.aasm.states(:permitted => false).map(&:name)
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(:permitted => true).map(&:name)
1193
+ job.aasm.events(permitted: true).map(&:name)
1110
1194
  #=> [:sleep]
1111
1195
 
1112
1196
  # show all non permitted events
1113
- job.aasm.events(:permitted => false).map(&:name)
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(:reject => :sleep).map(&:name)
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
- => [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
1206
+ #=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
1123
1207
 
1124
1208
  # show permitted states with guard parameter
1125
- job.aasm.states({:permitted => true}, guard_parameter).map(&:name)
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 :logger => Rails.logger do
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): `transition_from`, `have_state`, `allow_event` and `allow_transition_to`. Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this:
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
- Add `require 'aasm/minitest' to your `test_helper.rb` file and use them like this:
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.