aasm 5.0.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +243 -118
  3. data/lib/aasm/aasm.rb +29 -27
  4. data/lib/aasm/base.rb +61 -11
  5. data/lib/aasm/configuration.rb +3 -0
  6. data/lib/aasm/core/event.rb +21 -9
  7. data/lib/aasm/core/invokers/class_invoker.rb +1 -1
  8. data/lib/aasm/core/invokers/literal_invoker.rb +3 -1
  9. data/lib/aasm/core/state.rb +6 -5
  10. data/lib/aasm/core/transition.rb +1 -1
  11. data/lib/aasm/dsl_helper.rb +24 -22
  12. data/lib/aasm/errors.rb +3 -1
  13. data/lib/aasm/instance_base.rb +28 -5
  14. data/lib/aasm/localizer.rb +13 -3
  15. data/lib/aasm/persistence/active_record_persistence.rb +25 -5
  16. data/lib/aasm/persistence/base.rb +14 -3
  17. data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
  18. data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
  19. data/lib/aasm/persistence/mongoid_persistence.rb +1 -1
  20. data/lib/aasm/persistence/no_brainer_persistence.rb +1 -1
  21. data/lib/aasm/persistence/orm.rb +23 -19
  22. data/lib/aasm/persistence/redis_persistence.rb +1 -1
  23. data/lib/aasm/rspec/transition_from.rb +5 -1
  24. data/lib/aasm/version.rb +1 -1
  25. data/lib/aasm.rb +0 -2
  26. data/lib/generators/aasm/orm_helpers.rb +7 -1
  27. data/lib/generators/active_record/aasm_generator.rb +3 -1
  28. data/lib/generators/active_record/templates/migration.rb +1 -1
  29. metadata +35 -385
  30. data/.document +0 -6
  31. data/.gitignore +0 -20
  32. data/.travis.yml +0 -54
  33. data/API +0 -34
  34. data/Appraisals +0 -66
  35. data/CHANGELOG.md +0 -377
  36. data/CODE_OF_CONDUCT.md +0 -13
  37. data/CONTRIBUTING.md +0 -24
  38. data/Dockerfile +0 -44
  39. data/Gemfile +0 -6
  40. data/Gemfile.lock_old +0 -151
  41. data/HOWTO +0 -12
  42. data/PLANNED_CHANGES.md +0 -11
  43. data/README_FROM_VERSION_3_TO_4.md +0 -240
  44. data/Rakefile +0 -31
  45. data/TESTING.md +0 -25
  46. data/aasm.gemspec +0 -35
  47. data/callbacks.txt +0 -51
  48. data/docker-compose.yml +0 -40
  49. data/gemfiles/rails_3.2.gemfile +0 -13
  50. data/gemfiles/rails_4.0.gemfile +0 -15
  51. data/gemfiles/rails_4.2.gemfile +0 -16
  52. data/gemfiles/rails_4.2_mongoid_5.gemfile +0 -11
  53. data/gemfiles/rails_4.2_nobrainer.gemfile +0 -9
  54. data/gemfiles/rails_5.0.gemfile +0 -13
  55. data/gemfiles/rails_5.0_nobrainer.gemfile +0 -9
  56. data/gemfiles/rails_5.1.gemfile +0 -13
  57. data/spec/database.rb +0 -44
  58. data/spec/database.yml +0 -3
  59. data/spec/en.yml +0 -12
  60. data/spec/en_deprecated_style.yml +0 -10
  61. data/spec/generators/active_record_generator_spec.rb +0 -47
  62. data/spec/generators/mongoid_generator_spec.rb +0 -31
  63. data/spec/generators/no_brainer_generator_spec.rb +0 -29
  64. data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +0 -25
  65. data/spec/models/active_record/complex_active_record_example.rb +0 -37
  66. data/spec/models/active_record/derivate_new_dsl.rb +0 -7
  67. data/spec/models/active_record/false_state.rb +0 -35
  68. data/spec/models/active_record/gate.rb +0 -39
  69. data/spec/models/active_record/invalid_persistor.rb +0 -29
  70. data/spec/models/active_record/localizer_test_model.rb +0 -34
  71. data/spec/models/active_record/no_direct_assignment.rb +0 -21
  72. data/spec/models/active_record/no_scope.rb +0 -21
  73. data/spec/models/active_record/persisted_state.rb +0 -12
  74. data/spec/models/active_record/provided_and_persisted_state.rb +0 -24
  75. data/spec/models/active_record/reader.rb +0 -7
  76. data/spec/models/active_record/readme_job.rb +0 -21
  77. data/spec/models/active_record/silent_persistor.rb +0 -29
  78. data/spec/models/active_record/simple_new_dsl.rb +0 -17
  79. data/spec/models/active_record/thief.rb +0 -29
  80. data/spec/models/active_record/transactor.rb +0 -124
  81. data/spec/models/active_record/transient.rb +0 -6
  82. data/spec/models/active_record/validator.rb +0 -118
  83. data/spec/models/active_record/with_enum.rb +0 -39
  84. data/spec/models/active_record/with_enum_without_column.rb +0 -38
  85. data/spec/models/active_record/with_false_enum.rb +0 -31
  86. data/spec/models/active_record/with_true_enum.rb +0 -39
  87. data/spec/models/active_record/worker.rb +0 -2
  88. data/spec/models/active_record/writer.rb +0 -6
  89. data/spec/models/basic_two_state_machines_example.rb +0 -25
  90. data/spec/models/callbacks/basic.rb +0 -98
  91. data/spec/models/callbacks/basic_multiple.rb +0 -75
  92. data/spec/models/callbacks/guard_within_block.rb +0 -67
  93. data/spec/models/callbacks/guard_within_block_multiple.rb +0 -66
  94. data/spec/models/callbacks/multiple_transitions_transition_guard.rb +0 -66
  95. data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +0 -65
  96. data/spec/models/callbacks/private_method.rb +0 -44
  97. data/spec/models/callbacks/private_method_multiple.rb +0 -44
  98. data/spec/models/callbacks/with_args.rb +0 -62
  99. data/spec/models/callbacks/with_args_multiple.rb +0 -61
  100. data/spec/models/callbacks/with_state_arg.rb +0 -30
  101. data/spec/models/callbacks/with_state_arg_multiple.rb +0 -26
  102. data/spec/models/complex_example.rb +0 -222
  103. data/spec/models/conversation.rb +0 -93
  104. data/spec/models/default_state.rb +0 -12
  105. data/spec/models/double_definer.rb +0 -21
  106. data/spec/models/dynamoid/complex_dynamoid_example.rb +0 -37
  107. data/spec/models/dynamoid/dynamoid_multiple.rb +0 -18
  108. data/spec/models/dynamoid/dynamoid_simple.rb +0 -18
  109. data/spec/models/foo.rb +0 -106
  110. data/spec/models/foo_callback_multiple.rb +0 -45
  111. data/spec/models/guard_arguments_check.rb +0 -17
  112. data/spec/models/guard_with_params.rb +0 -24
  113. data/spec/models/guard_with_params_multiple.rb +0 -18
  114. data/spec/models/guardian.rb +0 -58
  115. data/spec/models/guardian_multiple.rb +0 -48
  116. data/spec/models/guardian_without_from_specified.rb +0 -18
  117. data/spec/models/initial_state_proc.rb +0 -31
  118. data/spec/models/mongoid/complex_mongoid_example.rb +0 -37
  119. data/spec/models/mongoid/invalid_persistor_mongoid.rb +0 -39
  120. data/spec/models/mongoid/mongoid_relationships.rb +0 -26
  121. data/spec/models/mongoid/no_scope_mongoid.rb +0 -21
  122. data/spec/models/mongoid/silent_persistor_mongoid.rb +0 -39
  123. data/spec/models/mongoid/simple_mongoid.rb +0 -23
  124. data/spec/models/mongoid/simple_new_dsl_mongoid.rb +0 -25
  125. data/spec/models/mongoid/validator_mongoid.rb +0 -100
  126. data/spec/models/multi_transitioner.rb +0 -34
  127. data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +0 -31
  128. data/spec/models/namespaced_multiple_example.rb +0 -42
  129. data/spec/models/no_initial_state.rb +0 -25
  130. data/spec/models/nobrainer/complex_no_brainer_example.rb +0 -36
  131. data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +0 -39
  132. data/spec/models/nobrainer/no_scope_no_brainer.rb +0 -21
  133. data/spec/models/nobrainer/nobrainer_relationships.rb +0 -25
  134. data/spec/models/nobrainer/silent_persistor_no_brainer.rb +0 -39
  135. data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +0 -25
  136. data/spec/models/nobrainer/simple_no_brainer.rb +0 -23
  137. data/spec/models/nobrainer/validator_no_brainer.rb +0 -98
  138. data/spec/models/not_auto_loaded/process.rb +0 -21
  139. data/spec/models/parametrised_event.rb +0 -42
  140. data/spec/models/parametrised_event_multiple.rb +0 -29
  141. data/spec/models/process_with_new_dsl.rb +0 -31
  142. data/spec/models/provided_state.rb +0 -24
  143. data/spec/models/redis/complex_redis_example.rb +0 -40
  144. data/spec/models/redis/redis_multiple.rb +0 -20
  145. data/spec/models/redis/redis_simple.rb +0 -20
  146. data/spec/models/sequel/complex_sequel_example.rb +0 -46
  147. data/spec/models/sequel/invalid_persistor.rb +0 -52
  148. data/spec/models/sequel/sequel_multiple.rb +0 -25
  149. data/spec/models/sequel/sequel_simple.rb +0 -26
  150. data/spec/models/sequel/silent_persistor.rb +0 -50
  151. data/spec/models/sequel/transactor.rb +0 -112
  152. data/spec/models/sequel/validator.rb +0 -93
  153. data/spec/models/sequel/worker.rb +0 -12
  154. data/spec/models/silencer.rb +0 -27
  155. data/spec/models/simple_custom_example.rb +0 -53
  156. data/spec/models/simple_example.rb +0 -17
  157. data/spec/models/simple_example_with_guard_args.rb +0 -17
  158. data/spec/models/simple_multiple_example.rb +0 -42
  159. data/spec/models/state_machine_with_failed_event.rb +0 -20
  160. data/spec/models/states_on_one_line_example.rb +0 -8
  161. data/spec/models/sub_class.rb +0 -41
  162. data/spec/models/sub_class_with_more_states.rb +0 -18
  163. data/spec/models/sub_classing.rb +0 -3
  164. data/spec/models/super_class.rb +0 -46
  165. data/spec/models/this_name_better_not_be_in_use.rb +0 -11
  166. data/spec/models/valid_state_name.rb +0 -23
  167. data/spec/spec_helper.rb +0 -26
  168. data/spec/spec_helpers/active_record.rb +0 -8
  169. data/spec/spec_helpers/dynamoid.rb +0 -35
  170. data/spec/spec_helpers/mongoid.rb +0 -26
  171. data/spec/spec_helpers/nobrainer.rb +0 -15
  172. data/spec/spec_helpers/redis.rb +0 -18
  173. data/spec/spec_helpers/remove_warnings.rb +0 -1
  174. data/spec/spec_helpers/sequel.rb +0 -7
  175. data/spec/unit/api_spec.rb +0 -100
  176. data/spec/unit/basic_two_state_machines_example_spec.rb +0 -10
  177. data/spec/unit/callback_multiple_spec.rb +0 -300
  178. data/spec/unit/callbacks_spec.rb +0 -491
  179. data/spec/unit/complex_example_spec.rb +0 -94
  180. data/spec/unit/complex_multiple_example_spec.rb +0 -115
  181. data/spec/unit/edge_cases_spec.rb +0 -16
  182. data/spec/unit/event_multiple_spec.rb +0 -73
  183. data/spec/unit/event_naming_spec.rb +0 -16
  184. data/spec/unit/event_spec.rb +0 -381
  185. data/spec/unit/exception_spec.rb +0 -11
  186. data/spec/unit/guard_arguments_check_spec.rb +0 -9
  187. data/spec/unit/guard_multiple_spec.rb +0 -60
  188. data/spec/unit/guard_spec.rb +0 -89
  189. data/spec/unit/guard_with_params_multiple_spec.rb +0 -10
  190. data/spec/unit/guard_with_params_spec.rb +0 -14
  191. data/spec/unit/guard_without_from_specified_spec.rb +0 -10
  192. data/spec/unit/initial_state_multiple_spec.rb +0 -15
  193. data/spec/unit/initial_state_spec.rb +0 -12
  194. data/spec/unit/inspection_multiple_spec.rb +0 -201
  195. data/spec/unit/inspection_spec.rb +0 -149
  196. data/spec/unit/invoker_spec.rb +0 -189
  197. data/spec/unit/invokers/base_invoker_spec.rb +0 -72
  198. data/spec/unit/invokers/class_invoker_spec.rb +0 -95
  199. data/spec/unit/invokers/literal_invoker_spec.rb +0 -86
  200. data/spec/unit/invokers/proc_invoker_spec.rb +0 -86
  201. data/spec/unit/localizer_spec.rb +0 -78
  202. data/spec/unit/memory_leak_spec.rb +0 -38
  203. data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +0 -14
  204. data/spec/unit/namespaced_multiple_example_spec.rb +0 -75
  205. data/spec/unit/new_dsl_spec.rb +0 -12
  206. data/spec/unit/override_warning_spec.rb +0 -94
  207. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +0 -618
  208. data/spec/unit/persistence/active_record_persistence_spec.rb +0 -735
  209. data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +0 -135
  210. data/spec/unit/persistence/dynamoid_persistence_spec.rb +0 -84
  211. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -200
  212. data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -165
  213. data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +0 -198
  214. data/spec/unit/persistence/no_brainer_persistence_spec.rb +0 -158
  215. data/spec/unit/persistence/redis_persistence_multiple_spec.rb +0 -88
  216. data/spec/unit/persistence/redis_persistence_spec.rb +0 -53
  217. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +0 -148
  218. data/spec/unit/persistence/sequel_persistence_spec.rb +0 -368
  219. data/spec/unit/readme_spec.rb +0 -41
  220. data/spec/unit/reloading_spec.rb +0 -15
  221. data/spec/unit/rspec_matcher_spec.rb +0 -85
  222. data/spec/unit/simple_custom_example_spec.rb +0 -39
  223. data/spec/unit/simple_example_spec.rb +0 -42
  224. data/spec/unit/simple_multiple_example_spec.rb +0 -91
  225. data/spec/unit/state_spec.rb +0 -89
  226. data/spec/unit/states_on_one_line_example_spec.rb +0 -16
  227. data/spec/unit/subclassing_multiple_spec.rb +0 -74
  228. data/spec/unit/subclassing_spec.rb +0 -46
  229. data/spec/unit/transition_spec.rb +0 -436
  230. data/test/minitest_helper.rb +0 -57
  231. data/test/unit/minitest_matcher_test.rb +0 -80
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)
@@ -20,6 +20,7 @@
20
20
  - [Extending AASM](#extending-aasm)
21
21
  - [ActiveRecord](#activerecord)
22
22
  - [Bang events](#bang-events)
23
+ - [Timestamps](#timestamps)
23
24
  - [ActiveRecord enums](#activerecord-enums)
24
25
  - [Sequel](#sequel)
25
26
  - [Dynamoid](#dynamoid)
@@ -30,6 +31,7 @@
30
31
  - [Transaction support](#transaction-support)
31
32
  - [Pessimistic Locking](#pessimistic-locking)
32
33
  - [Column name & migration](#column-name--migration)
34
+ - [Log State Changes](#log-state-changes)
33
35
  - [Inspection](#inspection)
34
36
  - [Warning output](#warning-output)
35
37
  - [RubyMotion support](#rubymotion-support)
@@ -71,19 +73,19 @@ class Job
71
73
  include AASM
72
74
 
73
75
  aasm do
74
- state :sleeping, :initial => true
76
+ state :sleeping, initial: true
75
77
  state :running, :cleaning
76
78
 
77
79
  event :run do
78
- transitions :from => :sleeping, :to => :running
80
+ transitions from: :sleeping, to: :running
79
81
  end
80
82
 
81
83
  event :clean do
82
- transitions :from => :running, :to => :cleaning
84
+ transitions from: :running, to: :cleaning
83
85
  end
84
86
 
85
87
  event :sleep do
86
- transitions :from => [:running, :cleaning], :to => :sleeping
88
+ transitions from: [:running, :cleaning], to: :sleeping
87
89
  end
88
90
  end
89
91
 
@@ -109,7 +111,7 @@ AASM not to be *whiny*:
109
111
  ```ruby
110
112
  class Job
111
113
  ...
112
- aasm :whiny_transitions => false do
114
+ aasm whiny_transitions: false do
113
115
  ...
114
116
  end
115
117
  end
@@ -134,33 +136,23 @@ You can define a number of callbacks for your events, transitions and states. Th
134
136
  called when certain criteria are met, like entering a particular state:
135
137
 
136
138
  ```ruby
137
- class LogRunTime
138
- def initialize(resource)
139
- @resource = resource
140
- end
141
-
142
- def call
143
- # Do whatever you want with @resource
144
- end
145
- end
146
-
147
139
  class Job
148
140
  include AASM
149
141
 
150
142
  aasm do
151
- state :sleeping, :initial => true, :before_enter => :do_something
143
+ state :sleeping, initial: true, before_enter: :do_something
152
144
  state :running, before_enter: Proc.new { do_something && notify_somebody }
153
145
  state :finished
154
146
 
155
147
  after_all_transitions :log_status_change
156
148
 
157
- event :run, :after => :notify_somebody do
149
+ event :run, after: :notify_somebody do
158
150
  before do
159
151
  log('Preparing to run')
160
152
  end
161
153
 
162
- transitions :from => :sleeping, :to => :running, :after => Proc.new {|*args| set_process(*args) }
163
- transitions :from => :running, :to => :finished, :after => LogRunTime
154
+ transitions from: :sleeping, to: :running, after: Proc.new {|*args| set_process(*args) }
155
+ transitions from: :running, to: :finished, after: LogRunTime
164
156
  end
165
157
 
166
158
  event :sleep do
@@ -170,7 +162,7 @@ class Job
170
162
  error do |e|
171
163
  ...
172
164
  end
173
- transitions :from => :running, :to => :sleeping
165
+ transitions from: :running, to: :sleeping
174
166
  end
175
167
  end
176
168
 
@@ -221,17 +213,28 @@ class LogRunTime
221
213
  end
222
214
  ```
223
215
 
224
- Also, you can pass parameters to events:
216
+ #### Parameters
217
+ You can pass parameters to events:
225
218
 
226
219
  ```ruby
227
220
  job = Job.new
228
- job.run(:running, :defragmentation)
221
+ job.run(:defragmentation)
229
222
  ```
230
223
 
231
- In this case the `set_process` would be called with `:defragmentation` argument.
224
+ All guards and after callbacks will receive these parameters. In this case `set_process` would be called with
225
+ `:defragmentation` argument.
226
+
227
+ If the first argument to the event is a state (e.g. `:running` or `:finished`), the first argument is consumed and
228
+ the state machine will attempt to transition to that state. Add comma separated parameter for guards and callbacks
232
229
 
233
- 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.
230
+ ```ruby
231
+ job = Job.new
232
+ job.run(:running, :defragmentation)
233
+ ```
234
+ In this case `set_process` won't be called, job will transition to running state and callback will receive
235
+ `:defragmentation` as parameter
234
236
 
237
+ #### Error Handling
235
238
  In case of an error during the event processing the error is rescued and passed to `:error`
236
239
  callback, which can handle it or re-raise it for further propagation.
237
240
 
@@ -271,8 +274,8 @@ begin
271
274
  new_state enter
272
275
  ...update state...
273
276
  event before_success # if persist successful
274
- transition success # if persist successful
275
- event success # if persist successful
277
+ transition success # if persist successful, database update not guaranteed
278
+ event success # if persist successful, database update not guaranteed
276
279
  old_state after_exit
277
280
  new_state after_enter
278
281
  event after
@@ -286,6 +289,8 @@ ensure
286
289
  end
287
290
  ```
288
291
 
292
+ Use event's `after_commit` callback if it should be fired after database update.
293
+
289
294
  #### The current event triggered
290
295
 
291
296
  While running the callbacks you can easily retrieve the name of the event triggered
@@ -316,31 +321,31 @@ and then
316
321
  Let's assume you want to allow particular transitions only if a defined condition is
317
322
  given. For this you can set up a guard per transition, which will run before actually
318
323
  running the transition. If the guard returns `false` the transition will be
319
- denied (raising `AASM::InvalidTransition` or returning `false` itself):
324
+ denied (raising `AASM::InvalidTransition`):
320
325
 
321
326
  ```ruby
322
327
  class Cleaner
323
328
  include AASM
324
329
 
325
330
  aasm do
326
- state :idle, :initial => true
331
+ state :idle, initial: true
327
332
  state :cleaning
328
333
 
329
334
  event :clean do
330
- transitions :from => :idle, :to => :cleaning, :guard => :cleaning_needed?
335
+ transitions from: :idle, to: :cleaning, guard: :cleaning_needed?
331
336
  end
332
337
 
333
338
  event :clean_if_needed do
334
- transitions :from => :idle, :to => :cleaning do
339
+ transitions from: :idle, to: :cleaning do
335
340
  guard do
336
341
  cleaning_needed?
337
342
  end
338
343
  end
339
- transitions :from => :idle, :to => :idle
344
+ transitions from: :idle, to: :idle
340
345
  end
341
346
 
342
347
  event :clean_if_dirty do
343
- transitions :from => :idle, :to => :cleaning, :guard => :if_dirty?
348
+ transitions from: :idle, to: :cleaning, guard: :if_dirty?
344
349
  end
345
350
  end
346
351
 
@@ -359,7 +364,7 @@ job.clean # => raises AASM::InvalidTransition
359
364
  job.may_clean_if_needed? # => true
360
365
  job.clean_if_needed! # idle
361
366
 
362
- job.clean_if_dirty(:clean) # => false
367
+ job.clean_if_dirty(:clean) # => raises AASM::InvalidTransition
363
368
  job.clean_if_dirty(:dirty) # => true
364
369
  ```
365
370
 
@@ -369,16 +374,16 @@ You can even provide a number of guards, which all have to succeed to proceed
369
374
  def walked_the_dog?; ...; end
370
375
 
371
376
  event :sleep do
372
- transitions :from => :running, :to => :sleeping, :guards => [:cleaning_needed?, :walked_the_dog?]
377
+ transitions from: :running, to: :sleeping, guards: [:cleaning_needed?, :walked_the_dog?]
373
378
  end
374
379
  ```
375
380
 
376
381
  If you want to provide guards for all transitions within an event, you can use event guards
377
382
 
378
383
  ```ruby
379
- event :sleep, :guards => [:walked_the_dog?] do
380
- transitions :from => :running, :to => :sleeping, :guards => [:cleaning_needed?]
381
- transitions :from => :cleaning, :to => :sleeping
384
+ event :sleep, guards: [:walked_the_dog?] do
385
+ transitions from: :running, to: :sleeping, guards: [:cleaning_needed?]
386
+ transitions from: :cleaning, to: :sleeping
382
387
  end
383
388
  ```
384
389
 
@@ -386,15 +391,30 @@ If you prefer a more Ruby-like guard syntax, you can use `if` and `unless` as we
386
391
 
387
392
  ```ruby
388
393
  event :clean do
389
- transitions :from => :running, :to => :cleaning, :if => :cleaning_needed?
394
+ transitions from: :running, to: :cleaning, if: :cleaning_needed?
390
395
  end
391
396
 
392
397
  event :sleep do
393
- transitions :from => :running, :to => :sleeping, :unless => :cleaning_needed?
398
+ transitions from: :running, to: :sleeping, unless: :cleaning_needed?
394
399
  end
395
400
  end
396
401
  ```
397
402
 
403
+ You can invoke a Class instead of a method if the Class responds to `call`
404
+
405
+ ```ruby
406
+ event :sleep do
407
+ transitions from: :running, to: :sleeping, guards: Dog
408
+ end
409
+ ```
410
+ ```ruby
411
+ class Dog
412
+ def call
413
+ cleaning_needed? && walked?
414
+ end
415
+ ...
416
+ end
417
+ ```
398
418
 
399
419
  ### Transitions
400
420
 
@@ -407,7 +427,7 @@ class Job
407
427
  include AASM
408
428
 
409
429
  aasm do
410
- state :stage1, :initial => true
430
+ state :stage1, initial: true
411
431
  state :stage2
412
432
  state :stage3
413
433
  state :completed
@@ -428,40 +448,67 @@ job.stage1_completed
428
448
  job.aasm.current_state # stage3
429
449
  ```
430
450
 
451
+ You can define transition from any defined state by omitting `from`:
452
+
453
+ ```ruby
454
+ event :abort do
455
+ transitions to: :aborted
456
+ end
457
+ ```
458
+
459
+ ### Display name for state
460
+
461
+ You can define display name for state using :display option
462
+
463
+ ```ruby
464
+ class Job
465
+ include AASM
466
+
467
+ aasm do
468
+ state :stage1, initial: true, display: 'First Stage'
469
+ state :stage2
470
+ state :stage3
471
+ end
472
+ end
473
+
474
+ job = Job.new
475
+ job.aasm.human_state
476
+
477
+ ```
431
478
 
432
479
  ### Multiple state machines per class
433
480
 
434
481
  Multiple state machines per class are supported. Be aware though that _AASM_ has been
435
- built with one state machine per class in mind. Nonetheless, here's how to do it:
482
+ 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.
436
483
 
437
484
  ```ruby
438
485
  class SimpleMultipleExample
439
486
  include AASM
440
- aasm(:move) do
441
- state :standing, :initial => true
487
+ aasm(:move, column: 'move_state') do
488
+ state :standing, initial: true
442
489
  state :walking
443
490
  state :running
444
491
 
445
492
  event :walk do
446
- transitions :from => :standing, :to => :walking
493
+ transitions from: :standing, to: :walking
447
494
  end
448
495
  event :run do
449
- transitions :from => [:standing, :walking], :to => :running
496
+ transitions from: [:standing, :walking], to: :running
450
497
  end
451
498
  event :hold do
452
- transitions :from => [:walking, :running], :to => :standing
499
+ transitions from: [:walking, :running], to: :standing
453
500
  end
454
501
  end
455
502
 
456
- aasm(:work) do
457
- state :sleeping, :initial => true
503
+ aasm(:work, column: 'work_state') do
504
+ state :sleeping, initial: true
458
505
  state :processing
459
506
 
460
507
  event :start do
461
- transitions :from => :sleeping, :to => :processing
508
+ transitions from: :sleeping, to: :processing
462
509
  end
463
510
  event :stop do
464
- transitions :from => :processing, :to => :sleeping
511
+ transitions from: :processing, to: :sleeping
465
512
  end
466
513
  end
467
514
  end
@@ -470,13 +517,13 @@ simple = SimpleMultipleExample.new
470
517
 
471
518
  simple.aasm(:move).current_state
472
519
  # => :standing
473
- simple.aasm(:work).current
520
+ simple.aasm(:work).current_state
474
521
  # => :sleeping
475
522
 
476
523
  simple.start
477
524
  simple.aasm(:move).current_state
478
525
  # => :standing
479
- simple.aasm(:work).current
526
+ simple.aasm(:work).current_state
480
527
  # => :processing
481
528
 
482
529
  ```
@@ -494,28 +541,28 @@ Alternatively, you can provide a namespace for each state machine:
494
541
  class NamespacedMultipleExample
495
542
  include AASM
496
543
  aasm(:status) do
497
- state :unapproved, :initial => true
544
+ state :unapproved, initial: true
498
545
  state :approved
499
546
 
500
547
  event :approve do
501
- transitions :from => :unapproved, :to => :approved
548
+ transitions from: :unapproved, to: :approved
502
549
  end
503
550
 
504
551
  event :unapprove do
505
- transitions :from => :approved, :to => :unapproved
552
+ transitions from: :approved, to: :unapproved
506
553
  end
507
554
  end
508
555
 
509
556
  aasm(:review_status, namespace: :review) do
510
- state :unapproved, :initial => true
557
+ state :unapproved, initial: true
511
558
  state :approved
512
559
 
513
560
  event :approve do
514
- transitions :from => :unapproved, :to => :approved
561
+ transitions from: :unapproved, to: :approved
515
562
  end
516
563
 
517
564
  event :unapprove do
518
- transitions :from => :approved, :to => :unapproved
565
+ transitions from: :approved, to: :unapproved
519
566
  end
520
567
  end
521
568
  end
@@ -547,26 +594,26 @@ class Example
547
594
  include AASM
548
595
 
549
596
  aasm(:work) do
550
- state :sleeping, :initial => true
597
+ state :sleeping, initial: true
551
598
  state :processing
552
599
 
553
600
  event :start do
554
- transitions :from => :sleeping, :to => :processing
601
+ transitions from: :sleeping, to: :processing
555
602
  end
556
603
  event :stop do
557
- transitions :from => :processing, :to => :sleeping
604
+ transitions from: :processing, to: :sleeping
558
605
  end
559
606
  end
560
607
 
561
608
  aasm(:question) do
562
- state :answered, :initial => true
609
+ state :answered, initial: true
563
610
  state :asked
564
611
 
565
- event :ask, :binding_event => :start do
566
- transitions :from => :answered, :to => :asked
612
+ event :ask, binding_event: :start do
613
+ transitions from: :answered, to: :asked
567
614
  end
568
- event :answer, :binding_event => :stop do
569
- transitions :from => :asked, :to => :answered
615
+ event :answer, binding_event: :stop do
616
+ transitions from: :asked, to: :answered
570
617
  end
571
618
  end
572
619
  end
@@ -612,7 +659,7 @@ class CustomAASMBase < AASM::Base
612
659
  # A custom transiton that we want available across many AASM models.
613
660
  def count_transitions!
614
661
  klass.class_eval do
615
- aasm :with_klass => CustomAASMBase do
662
+ aasm with_klass: CustomAASMBase do
616
663
  after_all_transitions :increment_transition_count
617
664
  end
618
665
  end
@@ -649,19 +696,19 @@ class SimpleCustomExample
649
696
  include AASM
650
697
 
651
698
  # Let's build an AASM state machine with our custom class.
652
- aasm :with_klass => CustomAASMBase do
699
+ aasm with_klass: CustomAASMBase do
653
700
  requires_guards!
654
701
  count_transitions!
655
702
 
656
- state :initialised, :initial => true
703
+ state :initialised, initial: true
657
704
  state :filled_out
658
705
  state :authorised
659
706
 
660
707
  event :fill_out do
661
- transitions :from => :initialised, :to => :filled_out, :guard => :fillable?
708
+ transitions from: :initialised, to: :filled_out, guard: :fillable?
662
709
  end
663
710
  event :authorise do
664
- transitions :from => :filled_out, :to => :authorised, :guard => :authorizable?
711
+ transitions from: :filled_out, to: :authorised, guard: :authorizable?
665
712
  end
666
713
  end
667
714
  end
@@ -673,20 +720,22 @@ end
673
720
  AASM comes with support for ActiveRecord and allows automatic persisting of the object's
674
721
  state in the database.
675
722
 
723
+ Add `gem 'after_commit_everywhere', '~> 1.0'` to your Gemfile.
724
+
676
725
  ```ruby
677
726
  class Job < ActiveRecord::Base
678
727
  include AASM
679
728
 
680
729
  aasm do # default column: aasm_state
681
- state :sleeping, :initial => true
730
+ state :sleeping, initial: true
682
731
  state :running
683
732
 
684
733
  event :run do
685
- transitions :from => :sleeping, :to => :running
734
+ transitions from: :sleeping, to: :running
686
735
  end
687
736
 
688
737
  event :sleep do
689
- transitions :from => :running, :to => :sleeping
738
+ transitions from: :running, to: :sleeping
690
739
  end
691
740
  end
692
741
 
@@ -709,7 +758,7 @@ job.aasm.fire!(:run) # saved
709
758
 
710
759
  Saving includes running all validations on the `Job` class. If
711
760
  `whiny_persistence` flag is set to `true`, exception is raised in case of
712
- failure. If `whiny_persistence` flag is set to false, methods with a bang return
761
+ failure. If `whiny_persistence` flag is set to `false`, methods with a bang return
713
762
  `true` if the state transition is successful or `false` if an error occurs.
714
763
 
715
764
  If you want make sure the state gets saved without running validations (and
@@ -721,22 +770,30 @@ be updated in the database (just like ActiveRecord `update_column` is working).
721
770
  class Job < ActiveRecord::Base
722
771
  include AASM
723
772
 
724
- aasm :skip_validation_on_save => true do
725
- state :sleeping, :initial => true
773
+ aasm skip_validation_on_save: true do
774
+ state :sleeping, initial: true
726
775
  state :running
727
776
 
728
777
  event :run do
729
- transitions :from => :sleeping, :to => :running
778
+ transitions from: :sleeping, to: :running
730
779
  end
731
780
 
732
781
  event :sleep do
733
- transitions :from => :running, :to => :sleeping
782
+ transitions from: :running, to: :sleeping
734
783
  end
735
784
  end
736
785
 
737
786
  end
738
787
  ```
739
788
 
789
+ Also, you can skip the validation at instance level with `some_event_name_without_validation!` method.
790
+ With this you have the flexibility of having validation for all your transitions by default and then skip it wherever required.
791
+ Please note that only state column will be updated as mentioned in the above example.
792
+
793
+ ```ruby
794
+ job.run_without_validation!
795
+ ```
796
+
740
797
  If you want to make sure that the _AASM_ column for storing the state is not directly assigned,
741
798
  configure _AASM_ to not allow direct assignment, like this:
742
799
 
@@ -744,12 +801,12 @@ configure _AASM_ to not allow direct assignment, like this:
744
801
  class Job < ActiveRecord::Base
745
802
  include AASM
746
803
 
747
- aasm :no_direct_assignment => true do
748
- state :sleeping, :initial => true
804
+ aasm no_direct_assignment: true do
805
+ state :sleeping, initial: true
749
806
  state :running
750
807
 
751
808
  event :run do
752
- transitions :from => :sleeping, :to => :running
809
+ transitions from: :sleeping, to: :running
753
810
  end
754
811
  end
755
812
 
@@ -765,6 +822,37 @@ job.aasm_state = :running # => raises AASM::NoDirectAssignmentError
765
822
  job.aasm_state # => 'sleeping'
766
823
  ```
767
824
 
825
+ ### Timestamps
826
+
827
+ You can tell _AASM_ to try to write a timestamp whenever a new state is entered.
828
+ If `timestamps: true` is set, _AASM_ will look for a field named like the new state plus `_at` and try to fill it:
829
+
830
+ ```ruby
831
+ class Job < ActiveRecord::Base
832
+ include AASM
833
+
834
+ aasm timestamps: true do
835
+ state :sleeping, initial: true
836
+ state :running
837
+
838
+ event :run do
839
+ transitions from: :sleeping, to: :running
840
+ end
841
+ end
842
+ end
843
+ ```
844
+
845
+ resulting in this:
846
+
847
+ ```ruby
848
+ job = Job.create
849
+ job.running_at # => nil
850
+ job.run!
851
+ job.running_at # => 2020-02-20 20:00:00
852
+ ```
853
+
854
+ Missing timestamp fields are silently ignored, so it is not necessary to have setters (such as ActiveRecord columns) for *all* states when using this option.
855
+
768
856
  #### ActiveRecord enums
769
857
 
770
858
  You can use
@@ -780,8 +868,8 @@ class Job < ActiveRecord::Base
780
868
  running: 99
781
869
  }
782
870
 
783
- aasm :column => :state, :enum => true do
784
- state :sleeping, :initial => true
871
+ aasm column: :state, enum: true do
872
+ state :sleeping, initial: true
785
873
  state :running
786
874
  end
787
875
  end
@@ -880,7 +968,7 @@ class Job < ActiveRecord::Base
880
968
  include AASM
881
969
 
882
970
  aasm do
883
- state :sleeping, :initial => true
971
+ state :sleeping, initial: true
884
972
  state :running
885
973
  state :cleaning
886
974
  end
@@ -909,8 +997,8 @@ defining the `AASM` states, like this:
909
997
  class Job < ActiveRecord::Base
910
998
  include AASM
911
999
 
912
- aasm :create_scopes => false do
913
- state :sleeping, :initial => true
1000
+ aasm create_scopes: false do
1001
+ state :sleeping, initial: true
914
1002
  state :running
915
1003
  state :cleaning
916
1004
  end
@@ -943,11 +1031,11 @@ class Job < ActiveRecord::Base
943
1031
  include AASM
944
1032
 
945
1033
  aasm do
946
- state :sleeping, :initial => true
1034
+ state :sleeping, initial: true
947
1035
  state :running
948
1036
 
949
- event :run, :after_commit => :notify_about_running_job do
950
- transitions :from => :sleeping, :to => :running
1037
+ event :run, after_commit: :notify_about_running_job do
1038
+ transitions from: :sleeping, to: :running
951
1039
  end
952
1040
  end
953
1041
 
@@ -969,18 +1057,24 @@ job.run
969
1057
  job.save! #notify_about_running_job is not run
970
1058
  ```
971
1059
 
1060
+ Please note that `:after_commit` AASM callbacks behaves around custom implementation
1061
+ of transaction pattern rather than a real-life DB transaction. This fact still causes
1062
+ the race conditions and redundant callback calls within nested transaction. In order
1063
+ to fix that it's highly recommended to add `gem 'after_commit_everywhere', '~> 1.0'`
1064
+ to your `Gemfile`.
1065
+
972
1066
  If you want to encapsulate state changes within an own transaction, the behavior
973
1067
  of this nested transaction might be confusing. Take a look at
974
1068
  [ActiveRecord Nested Transactions](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)
975
1069
  if you want to know more about this. Nevertheless, AASM by default requires a new transaction
976
- `transaction(:requires_new => true)`. You can override this behavior by changing
1070
+ `transaction(requires_new: true)`. You can override this behavior by changing
977
1071
  the configuration
978
1072
 
979
1073
  ```ruby
980
1074
  class Job < ActiveRecord::Base
981
1075
  include AASM
982
1076
 
983
- aasm :requires_new_transaction => false do
1077
+ aasm requires_new_transaction: false do
984
1078
  ...
985
1079
  end
986
1080
 
@@ -988,9 +1082,9 @@ class Job < ActiveRecord::Base
988
1082
  end
989
1083
  ```
990
1084
 
991
- which then leads to `transaction(:requires_new => false)`, the Rails default.
1085
+ which then leads to `transaction(requires_new: false)`, the Rails default.
992
1086
 
993
- Additionally, if you do not want any of your active record actions to be
1087
+ Additionally, if you do not want any of your ActiveRecord actions to be
994
1088
  wrapped in a transaction, you can specify the `use_transactions` flag. This can
995
1089
  be useful if you want want to persist things to the database that happen as a
996
1090
  result of a transaction or callback, even when some error occurs. The
@@ -1000,7 +1094,7 @@ result of a transaction or callback, even when some error occurs. The
1000
1094
  class Job < ActiveRecord::Base
1001
1095
  include AASM
1002
1096
 
1003
- aasm :use_transactions => false do
1097
+ aasm use_transactions: false do
1004
1098
  ...
1005
1099
  end
1006
1100
 
@@ -1010,7 +1104,7 @@ end
1010
1104
 
1011
1105
  ### Pessimistic Locking
1012
1106
 
1013
- AASM supports [Active Record pessimistic locking via `with_lock`](http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html#method-i-with_lock) for database persistence layers.
1107
+ AASM supports [ActiveRecord pessimistic locking via `with_lock`](http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html#method-i-with_lock) for database persistence layers.
1014
1108
 
1015
1109
  | Option | Purpose |
1016
1110
  | ------ | ------- |
@@ -1023,7 +1117,7 @@ AASM supports [Active Record pessimistic locking via `with_lock`](http://api.rub
1023
1117
  class Job < ActiveRecord::Base
1024
1118
  include AASM
1025
1119
 
1026
- aasm :requires_lock => true do
1120
+ aasm requires_lock: true do
1027
1121
  ...
1028
1122
  end
1029
1123
 
@@ -1035,7 +1129,7 @@ end
1035
1129
  class Job < ActiveRecord::Base
1036
1130
  include AASM
1037
1131
 
1038
- aasm :requires_lock => 'FOR UPDATE NOWAIT' do
1132
+ aasm requires_lock: 'FOR UPDATE NOWAIT' do
1039
1133
  ...
1040
1134
  end
1041
1135
 
@@ -1053,18 +1147,21 @@ this by defining your favorite column name, using `:column` like this:
1053
1147
  class Job < ActiveRecord::Base
1054
1148
  include AASM
1055
1149
 
1056
- aasm :column => 'my_state' do
1150
+ aasm column: :my_state do
1057
1151
  ...
1058
1152
  end
1059
1153
 
1060
- aasm :another_state_machine, column: 'second_state' do
1154
+ aasm :another_state_machine, column: :second_state do
1061
1155
  ...
1062
1156
  end
1063
1157
  end
1064
1158
  ```
1065
1159
 
1066
1160
  Whatever column name is used, make sure to add a migration to provide this column
1067
- (of type `string`):
1161
+ (of type `string`).
1162
+ Do not add default value for column at the database level. If you add default
1163
+ value in database then AASM callbacks on the initial state will not be fired upon
1164
+ instantiation of the model.
1068
1165
 
1069
1166
  ```ruby
1070
1167
  class AddJobState < ActiveRecord::Migration
@@ -1078,6 +1175,13 @@ class AddJobState < ActiveRecord::Migration
1078
1175
  end
1079
1176
  ```
1080
1177
 
1178
+ ### Log State Changes
1179
+
1180
+ Logging state change can be done using [paper_trail](https://github.com/paper-trail-gem/paper_trail) gem
1181
+
1182
+ Example of implementation can be found here [https://github.com/nitsujri/aasm-papertrail-example](https://github.com/nitsujri/aasm-papertrail-example)
1183
+
1184
+
1081
1185
  ### Inspection
1082
1186
 
1083
1187
  AASM supports query methods for states and events
@@ -1089,19 +1193,19 @@ class Job
1089
1193
  include AASM
1090
1194
 
1091
1195
  aasm do
1092
- state :sleeping, :initial => true
1196
+ state :sleeping, initial: true
1093
1197
  state :running, :cleaning
1094
1198
 
1095
1199
  event :run do
1096
- transitions :from => :sleeping, :to => :running
1200
+ transitions from: :sleeping, to: :running
1097
1201
  end
1098
1202
 
1099
1203
  event :clean do
1100
- transitions :from => :running, :to => :cleaning, :guard => :cleaning_needed?
1204
+ transitions from: :running, to: :cleaning, guard: :cleaning_needed?
1101
1205
  end
1102
1206
 
1103
1207
  event :sleep do
1104
- transitions :from => [:running, :cleaning], :to => :sleeping
1208
+ transitions from: [:running, :cleaning], to: :sleeping
1105
1209
  end
1106
1210
  end
1107
1211
 
@@ -1119,15 +1223,19 @@ Job.aasm.states.map(&:name)
1119
1223
  job = Job.new
1120
1224
 
1121
1225
  # show all permitted states (from initial state)
1122
- job.aasm.states(:permitted => true).map(&:name)
1226
+ job.aasm.states(permitted: true).map(&:name)
1123
1227
  #=> [:running]
1124
1228
 
1229
+ # List all the permitted transitions(event and state pairs) from initial state
1230
+ job.aasm.permitted_transitions
1231
+ #=> [{ :event => :run, :state => :running }]
1232
+
1125
1233
  job.run
1126
- job.aasm.states(:permitted => true).map(&:name)
1234
+ job.aasm.states(permitted: true).map(&:name)
1127
1235
  #=> [:sleeping]
1128
1236
 
1129
1237
  # show all non permitted states
1130
- job.aasm.states(:permitted => false).map(&:name)
1238
+ job.aasm.states(permitted: false).map(&:name)
1131
1239
  #=> [:cleaning]
1132
1240
 
1133
1241
  # show all possible (triggerable) events from the current state
@@ -1135,23 +1243,23 @@ job.aasm.events.map(&:name)
1135
1243
  #=> [:clean, :sleep]
1136
1244
 
1137
1245
  # show all permitted events
1138
- job.aasm.events(:permitted => true).map(&:name)
1246
+ job.aasm.events(permitted: true).map(&:name)
1139
1247
  #=> [:sleep]
1140
1248
 
1141
1249
  # show all non permitted events
1142
- job.aasm.events(:permitted => false).map(&:name)
1250
+ job.aasm.events(permitted: false).map(&:name)
1143
1251
  #=> [:clean]
1144
1252
 
1145
1253
  # show all possible events except a specific one
1146
- job.aasm.events(:reject => :sleep).map(&:name)
1254
+ job.aasm.events(reject: :sleep).map(&:name)
1147
1255
  #=> [:clean]
1148
1256
 
1149
1257
  # list states for select
1150
1258
  Job.aasm.states_for_select
1151
- => [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
1259
+ #=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
1152
1260
 
1153
1261
  # show permitted states with guard parameter
1154
- job.aasm.states({:permitted => true}, guard_parameter).map(&:name)
1262
+ job.aasm.states({permitted: true}, guard_parameter).map(&:name)
1155
1263
  ```
1156
1264
 
1157
1265
 
@@ -1164,7 +1272,7 @@ use
1164
1272
  class Job
1165
1273
  include AASM
1166
1274
 
1167
- aasm :logger => Rails.logger do
1275
+ aasm logger: Rails.logger do
1168
1276
  ...
1169
1277
  end
1170
1278
  end
@@ -1188,7 +1296,15 @@ the 'instance method symbol / string' way whenever possible when defining guardi
1188
1296
 
1189
1297
  #### RSpec
1190
1298
 
1191
- 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:
1299
+ AASM provides some matchers for [RSpec](http://rspec.info):
1300
+ * `transition_from`,
1301
+ * `have_state`, `allow_event`
1302
+ * and `allow_transition_to`.
1303
+
1304
+ ##### Installation Instructions:
1305
+ * Add `require 'aasm/rspec'` to your `spec_helper.rb` file.
1306
+
1307
+ ##### Examples Of Usage in Rspec:
1192
1308
 
1193
1309
  ```ruby
1194
1310
  # classes with only the default state machine
@@ -1201,7 +1317,7 @@ expect(job).to allow_event :run
1201
1317
  expect(job).to_not allow_event :clean
1202
1318
  expect(job).to allow_transition_to(:running)
1203
1319
  expect(job).to_not allow_transition_to(:cleaning)
1204
- # on_event also accept arguments
1320
+ # on_event also accept multiple arguments
1205
1321
  expect(job).to transition_from(:sleeping).to(:running).on_event(:run, :defragmentation)
1206
1322
 
1207
1323
  # classes with multiple state machine
@@ -1235,6 +1351,9 @@ AASM provides assertions and rspec-like expectations for [Minitest](https://gith
1235
1351
 
1236
1352
  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`.
1237
1353
 
1354
+
1355
+ ##### Examples Of Usage (Minitest):
1356
+
1238
1357
  Add `require 'aasm/minitest'` to your `test_helper.rb` file and use them like this:
1239
1358
 
1240
1359
  ```ruby
@@ -1342,7 +1461,7 @@ After installing AASM you can run generator:
1342
1461
  ```
1343
1462
  Replace NAME with the Model name, COLUMN_NAME is optional(default is 'aasm_state').
1344
1463
  This will create a model (if one does not exist) and configure it with aasm block.
1345
- For Active record orm a migration file is added to add aasm state column to table.
1464
+ For ActiveRecord orm a migration file is added to add aasm state column to table.
1346
1465
 
1347
1466
  ### Docker
1348
1467
 
@@ -1372,6 +1491,12 @@ Feel free to
1372
1491
  * [Anil Maurya](http://github.com/anilmaurya) (since 2016)
1373
1492
 
1374
1493
 
1494
+
1495
+ ## Stargazers over time
1496
+
1497
+ [![Stargazers over time](https://starchart.cc/aasm/aasm.svg)](https://starchart.cc/aasm/aasm)
1498
+
1499
+
1375
1500
  ## [Contributing](CONTRIBUTING.md)
1376
1501
 
1377
1502
  ## Warranty ##