aasm 5.0.1 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +243 -108
- data/lib/aasm/aasm.rb +29 -27
- data/lib/aasm/base.rb +61 -11
- data/lib/aasm/configuration.rb +3 -0
- data/lib/aasm/core/event.rb +21 -10
- data/lib/aasm/core/invokers/class_invoker.rb +1 -1
- data/lib/aasm/core/invokers/literal_invoker.rb +3 -1
- data/lib/aasm/core/state.rb +6 -5
- data/lib/aasm/core/transition.rb +1 -1
- data/lib/aasm/dsl_helper.rb +24 -22
- data/lib/aasm/errors.rb +3 -1
- data/lib/aasm/instance_base.rb +28 -5
- data/lib/aasm/localizer.rb +13 -3
- data/lib/aasm/persistence/active_record_persistence.rb +20 -1
- data/lib/aasm/persistence/base.rb +14 -3
- data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
- data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
- data/lib/aasm/persistence/mongoid_persistence.rb +1 -1
- data/lib/aasm/persistence/no_brainer_persistence.rb +1 -1
- data/lib/aasm/persistence/orm.rb +23 -19
- data/lib/aasm/persistence/redis_persistence.rb +1 -1
- data/lib/aasm/rspec/transition_from.rb +5 -1
- data/lib/aasm/version.rb +1 -1
- data/lib/aasm.rb +0 -2
- data/lib/generators/aasm/orm_helpers.rb +7 -1
- data/lib/generators/active_record/aasm_generator.rb +3 -1
- data/lib/generators/active_record/templates/migration.rb +1 -1
- metadata +35 -385
- data/.document +0 -6
- data/.gitignore +0 -20
- data/.travis.yml +0 -54
- data/API +0 -34
- data/Appraisals +0 -66
- data/CHANGELOG.md +0 -383
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -24
- data/Dockerfile +0 -44
- data/Gemfile +0 -6
- data/Gemfile.lock_old +0 -151
- data/HOWTO +0 -12
- data/PLANNED_CHANGES.md +0 -11
- data/README_FROM_VERSION_3_TO_4.md +0 -240
- data/Rakefile +0 -31
- data/TESTING.md +0 -25
- data/aasm.gemspec +0 -35
- data/callbacks.txt +0 -51
- data/docker-compose.yml +0 -40
- data/gemfiles/rails_3.2.gemfile +0 -13
- data/gemfiles/rails_4.0.gemfile +0 -15
- data/gemfiles/rails_4.2.gemfile +0 -16
- data/gemfiles/rails_4.2_mongoid_5.gemfile +0 -11
- data/gemfiles/rails_4.2_nobrainer.gemfile +0 -9
- data/gemfiles/rails_5.0.gemfile +0 -13
- data/gemfiles/rails_5.0_nobrainer.gemfile +0 -9
- data/gemfiles/rails_5.1.gemfile +0 -13
- data/spec/database.rb +0 -47
- data/spec/database.yml +0 -3
- data/spec/en.yml +0 -12
- data/spec/en_deprecated_style.yml +0 -10
- data/spec/generators/active_record_generator_spec.rb +0 -47
- data/spec/generators/mongoid_generator_spec.rb +0 -31
- data/spec/generators/no_brainer_generator_spec.rb +0 -29
- data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +0 -25
- data/spec/models/active_record/complex_active_record_example.rb +0 -37
- data/spec/models/active_record/derivate_new_dsl.rb +0 -7
- data/spec/models/active_record/false_state.rb +0 -35
- data/spec/models/active_record/gate.rb +0 -39
- data/spec/models/active_record/invalid_persistor.rb +0 -29
- data/spec/models/active_record/localizer_test_model.rb +0 -34
- data/spec/models/active_record/no_direct_assignment.rb +0 -21
- data/spec/models/active_record/no_scope.rb +0 -21
- data/spec/models/active_record/persisted_state.rb +0 -12
- data/spec/models/active_record/provided_and_persisted_state.rb +0 -24
- data/spec/models/active_record/reader.rb +0 -7
- data/spec/models/active_record/readme_job.rb +0 -21
- data/spec/models/active_record/silent_persistor.rb +0 -29
- data/spec/models/active_record/simple_new_dsl.rb +0 -32
- data/spec/models/active_record/thief.rb +0 -29
- data/spec/models/active_record/transactor.rb +0 -124
- data/spec/models/active_record/transient.rb +0 -6
- data/spec/models/active_record/validator.rb +0 -118
- data/spec/models/active_record/with_enum.rb +0 -39
- data/spec/models/active_record/with_enum_without_column.rb +0 -38
- data/spec/models/active_record/with_false_enum.rb +0 -31
- data/spec/models/active_record/with_true_enum.rb +0 -39
- data/spec/models/active_record/worker.rb +0 -2
- data/spec/models/active_record/writer.rb +0 -6
- data/spec/models/basic_two_state_machines_example.rb +0 -25
- data/spec/models/callbacks/basic.rb +0 -98
- data/spec/models/callbacks/basic_multiple.rb +0 -75
- data/spec/models/callbacks/guard_within_block.rb +0 -67
- data/spec/models/callbacks/guard_within_block_multiple.rb +0 -66
- data/spec/models/callbacks/multiple_transitions_transition_guard.rb +0 -66
- data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +0 -65
- data/spec/models/callbacks/private_method.rb +0 -44
- data/spec/models/callbacks/private_method_multiple.rb +0 -44
- data/spec/models/callbacks/with_args.rb +0 -62
- data/spec/models/callbacks/with_args_multiple.rb +0 -61
- data/spec/models/callbacks/with_state_arg.rb +0 -30
- data/spec/models/callbacks/with_state_arg_multiple.rb +0 -26
- data/spec/models/complex_example.rb +0 -222
- data/spec/models/conversation.rb +0 -93
- data/spec/models/default_state.rb +0 -12
- data/spec/models/double_definer.rb +0 -21
- data/spec/models/dynamoid/complex_dynamoid_example.rb +0 -37
- data/spec/models/dynamoid/dynamoid_multiple.rb +0 -18
- data/spec/models/dynamoid/dynamoid_simple.rb +0 -18
- data/spec/models/foo.rb +0 -106
- data/spec/models/foo_callback_multiple.rb +0 -45
- data/spec/models/guard_arguments_check.rb +0 -17
- data/spec/models/guard_with_params.rb +0 -24
- data/spec/models/guard_with_params_multiple.rb +0 -18
- data/spec/models/guardian.rb +0 -58
- data/spec/models/guardian_multiple.rb +0 -48
- data/spec/models/guardian_without_from_specified.rb +0 -18
- data/spec/models/initial_state_proc.rb +0 -31
- data/spec/models/mongoid/complex_mongoid_example.rb +0 -37
- data/spec/models/mongoid/invalid_persistor_mongoid.rb +0 -39
- data/spec/models/mongoid/mongoid_relationships.rb +0 -26
- data/spec/models/mongoid/no_scope_mongoid.rb +0 -21
- data/spec/models/mongoid/silent_persistor_mongoid.rb +0 -39
- data/spec/models/mongoid/simple_mongoid.rb +0 -23
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +0 -25
- data/spec/models/mongoid/validator_mongoid.rb +0 -100
- data/spec/models/multi_transitioner.rb +0 -34
- data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +0 -31
- data/spec/models/namespaced_multiple_example.rb +0 -42
- data/spec/models/no_initial_state.rb +0 -25
- data/spec/models/nobrainer/complex_no_brainer_example.rb +0 -36
- data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +0 -39
- data/spec/models/nobrainer/no_scope_no_brainer.rb +0 -21
- data/spec/models/nobrainer/nobrainer_relationships.rb +0 -25
- data/spec/models/nobrainer/silent_persistor_no_brainer.rb +0 -39
- data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +0 -25
- data/spec/models/nobrainer/simple_no_brainer.rb +0 -23
- data/spec/models/nobrainer/validator_no_brainer.rb +0 -98
- data/spec/models/not_auto_loaded/process.rb +0 -21
- data/spec/models/parametrised_event.rb +0 -42
- data/spec/models/parametrised_event_multiple.rb +0 -29
- data/spec/models/process_with_new_dsl.rb +0 -31
- data/spec/models/provided_state.rb +0 -24
- data/spec/models/redis/complex_redis_example.rb +0 -40
- data/spec/models/redis/redis_multiple.rb +0 -20
- data/spec/models/redis/redis_simple.rb +0 -20
- data/spec/models/sequel/complex_sequel_example.rb +0 -46
- data/spec/models/sequel/invalid_persistor.rb +0 -52
- data/spec/models/sequel/sequel_multiple.rb +0 -25
- data/spec/models/sequel/sequel_simple.rb +0 -26
- data/spec/models/sequel/silent_persistor.rb +0 -50
- data/spec/models/sequel/transactor.rb +0 -112
- data/spec/models/sequel/validator.rb +0 -93
- data/spec/models/sequel/worker.rb +0 -12
- data/spec/models/silencer.rb +0 -27
- data/spec/models/simple_custom_example.rb +0 -53
- data/spec/models/simple_example.rb +0 -17
- data/spec/models/simple_example_with_guard_args.rb +0 -17
- data/spec/models/simple_multiple_example.rb +0 -42
- data/spec/models/state_machine_with_failed_event.rb +0 -20
- data/spec/models/states_on_one_line_example.rb +0 -8
- data/spec/models/sub_class.rb +0 -41
- data/spec/models/sub_class_with_more_states.rb +0 -18
- data/spec/models/sub_classing.rb +0 -3
- data/spec/models/super_class.rb +0 -46
- data/spec/models/this_name_better_not_be_in_use.rb +0 -11
- data/spec/models/valid_state_name.rb +0 -23
- data/spec/spec_helper.rb +0 -26
- data/spec/spec_helpers/active_record.rb +0 -8
- data/spec/spec_helpers/dynamoid.rb +0 -35
- data/spec/spec_helpers/mongoid.rb +0 -26
- data/spec/spec_helpers/nobrainer.rb +0 -15
- data/spec/spec_helpers/redis.rb +0 -18
- data/spec/spec_helpers/remove_warnings.rb +0 -1
- data/spec/spec_helpers/sequel.rb +0 -7
- data/spec/unit/api_spec.rb +0 -100
- data/spec/unit/basic_two_state_machines_example_spec.rb +0 -10
- data/spec/unit/callback_multiple_spec.rb +0 -300
- data/spec/unit/callbacks_spec.rb +0 -491
- data/spec/unit/complex_example_spec.rb +0 -94
- data/spec/unit/complex_multiple_example_spec.rb +0 -115
- data/spec/unit/edge_cases_spec.rb +0 -16
- data/spec/unit/event_multiple_spec.rb +0 -73
- data/spec/unit/event_naming_spec.rb +0 -16
- data/spec/unit/event_spec.rb +0 -381
- data/spec/unit/exception_spec.rb +0 -11
- data/spec/unit/guard_arguments_check_spec.rb +0 -9
- data/spec/unit/guard_multiple_spec.rb +0 -60
- data/spec/unit/guard_spec.rb +0 -89
- data/spec/unit/guard_with_params_multiple_spec.rb +0 -10
- data/spec/unit/guard_with_params_spec.rb +0 -14
- data/spec/unit/guard_without_from_specified_spec.rb +0 -10
- data/spec/unit/initial_state_multiple_spec.rb +0 -15
- data/spec/unit/initial_state_spec.rb +0 -12
- data/spec/unit/inspection_multiple_spec.rb +0 -201
- data/spec/unit/inspection_spec.rb +0 -149
- data/spec/unit/invoker_spec.rb +0 -189
- data/spec/unit/invokers/base_invoker_spec.rb +0 -72
- data/spec/unit/invokers/class_invoker_spec.rb +0 -95
- data/spec/unit/invokers/literal_invoker_spec.rb +0 -86
- data/spec/unit/invokers/proc_invoker_spec.rb +0 -86
- data/spec/unit/localizer_spec.rb +0 -78
- data/spec/unit/memory_leak_spec.rb +0 -38
- data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +0 -14
- data/spec/unit/namespaced_multiple_example_spec.rb +0 -75
- data/spec/unit/new_dsl_spec.rb +0 -12
- data/spec/unit/override_warning_spec.rb +0 -94
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +0 -618
- data/spec/unit/persistence/active_record_persistence_spec.rb +0 -751
- data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +0 -135
- data/spec/unit/persistence/dynamoid_persistence_spec.rb +0 -84
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -200
- data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -165
- data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +0 -198
- data/spec/unit/persistence/no_brainer_persistence_spec.rb +0 -158
- data/spec/unit/persistence/redis_persistence_multiple_spec.rb +0 -88
- data/spec/unit/persistence/redis_persistence_spec.rb +0 -53
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +0 -148
- data/spec/unit/persistence/sequel_persistence_spec.rb +0 -368
- data/spec/unit/readme_spec.rb +0 -41
- data/spec/unit/reloading_spec.rb +0 -15
- data/spec/unit/rspec_matcher_spec.rb +0 -85
- data/spec/unit/simple_custom_example_spec.rb +0 -39
- data/spec/unit/simple_example_spec.rb +0 -42
- data/spec/unit/simple_multiple_example_spec.rb +0 -91
- data/spec/unit/state_spec.rb +0 -89
- data/spec/unit/states_on_one_line_example_spec.rb +0 -16
- data/spec/unit/subclassing_multiple_spec.rb +0 -74
- data/spec/unit/subclassing_spec.rb +0 -46
- data/spec/unit/transition_spec.rb +0 -436
- data/test/minitest_helper.rb +0 -57
- 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, :
|
76
|
+
state :sleeping, initial: true
|
75
77
|
state :running, :cleaning
|
76
78
|
|
77
79
|
event :run do
|
78
|
-
transitions :
|
80
|
+
transitions from: :sleeping, to: :running
|
79
81
|
end
|
80
82
|
|
81
83
|
event :clean do
|
82
|
-
transitions :
|
84
|
+
transitions from: :running, to: :cleaning
|
83
85
|
end
|
84
86
|
|
85
87
|
event :sleep do
|
86
|
-
transitions :
|
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 :
|
114
|
+
aasm whiny_transitions: false do
|
113
115
|
...
|
114
116
|
end
|
115
117
|
end
|
@@ -138,19 +140,19 @@ class Job
|
|
138
140
|
include AASM
|
139
141
|
|
140
142
|
aasm do
|
141
|
-
state :sleeping, :
|
143
|
+
state :sleeping, initial: true, before_enter: :do_something
|
142
144
|
state :running, before_enter: Proc.new { do_something && notify_somebody }
|
143
145
|
state :finished
|
144
146
|
|
145
147
|
after_all_transitions :log_status_change
|
146
148
|
|
147
|
-
event :run, :
|
149
|
+
event :run, after: :notify_somebody do
|
148
150
|
before do
|
149
151
|
log('Preparing to run')
|
150
152
|
end
|
151
153
|
|
152
|
-
transitions :
|
153
|
-
transitions :
|
154
|
+
transitions from: :sleeping, to: :running, after: Proc.new {|*args| set_process(*args) }
|
155
|
+
transitions from: :running, to: :finished, after: LogRunTime
|
154
156
|
end
|
155
157
|
|
156
158
|
event :sleep do
|
@@ -160,7 +162,7 @@ class Job
|
|
160
162
|
error do |e|
|
161
163
|
...
|
162
164
|
end
|
163
|
-
transitions :
|
165
|
+
transitions from: :running, to: :sleeping
|
164
166
|
end
|
165
167
|
end
|
166
168
|
|
@@ -211,17 +213,28 @@ class LogRunTime
|
|
211
213
|
end
|
212
214
|
```
|
213
215
|
|
214
|
-
|
216
|
+
#### Parameters
|
217
|
+
You can pass parameters to events:
|
215
218
|
|
216
219
|
```ruby
|
217
220
|
job = Job.new
|
218
|
-
job.run(:
|
221
|
+
job.run(:defragmentation)
|
219
222
|
```
|
220
223
|
|
221
|
-
In this case
|
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
|
222
229
|
|
223
|
-
|
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
|
224
236
|
|
237
|
+
#### Error Handling
|
225
238
|
In case of an error during the event processing the error is rescued and passed to `:error`
|
226
239
|
callback, which can handle it or re-raise it for further propagation.
|
227
240
|
|
@@ -261,8 +274,8 @@ begin
|
|
261
274
|
new_state enter
|
262
275
|
...update state...
|
263
276
|
event before_success # if persist successful
|
264
|
-
transition success # if persist successful
|
265
|
-
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
|
266
279
|
old_state after_exit
|
267
280
|
new_state after_enter
|
268
281
|
event after
|
@@ -276,6 +289,8 @@ ensure
|
|
276
289
|
end
|
277
290
|
```
|
278
291
|
|
292
|
+
Use event's `after_commit` callback if it should be fired after database update.
|
293
|
+
|
279
294
|
#### The current event triggered
|
280
295
|
|
281
296
|
While running the callbacks you can easily retrieve the name of the event triggered
|
@@ -306,31 +321,31 @@ and then
|
|
306
321
|
Let's assume you want to allow particular transitions only if a defined condition is
|
307
322
|
given. For this you can set up a guard per transition, which will run before actually
|
308
323
|
running the transition. If the guard returns `false` the transition will be
|
309
|
-
denied (raising `AASM::InvalidTransition`
|
324
|
+
denied (raising `AASM::InvalidTransition`):
|
310
325
|
|
311
326
|
```ruby
|
312
327
|
class Cleaner
|
313
328
|
include AASM
|
314
329
|
|
315
330
|
aasm do
|
316
|
-
state :idle, :
|
331
|
+
state :idle, initial: true
|
317
332
|
state :cleaning
|
318
333
|
|
319
334
|
event :clean do
|
320
|
-
transitions :
|
335
|
+
transitions from: :idle, to: :cleaning, guard: :cleaning_needed?
|
321
336
|
end
|
322
337
|
|
323
338
|
event :clean_if_needed do
|
324
|
-
transitions :
|
339
|
+
transitions from: :idle, to: :cleaning do
|
325
340
|
guard do
|
326
341
|
cleaning_needed?
|
327
342
|
end
|
328
343
|
end
|
329
|
-
transitions :
|
344
|
+
transitions from: :idle, to: :idle
|
330
345
|
end
|
331
346
|
|
332
347
|
event :clean_if_dirty do
|
333
|
-
transitions :
|
348
|
+
transitions from: :idle, to: :cleaning, guard: :if_dirty?
|
334
349
|
end
|
335
350
|
end
|
336
351
|
|
@@ -349,7 +364,7 @@ job.clean # => raises AASM::InvalidTransition
|
|
349
364
|
job.may_clean_if_needed? # => true
|
350
365
|
job.clean_if_needed! # idle
|
351
366
|
|
352
|
-
job.clean_if_dirty(:clean) # =>
|
367
|
+
job.clean_if_dirty(:clean) # => raises AASM::InvalidTransition
|
353
368
|
job.clean_if_dirty(:dirty) # => true
|
354
369
|
```
|
355
370
|
|
@@ -359,16 +374,16 @@ You can even provide a number of guards, which all have to succeed to proceed
|
|
359
374
|
def walked_the_dog?; ...; end
|
360
375
|
|
361
376
|
event :sleep do
|
362
|
-
transitions :
|
377
|
+
transitions from: :running, to: :sleeping, guards: [:cleaning_needed?, :walked_the_dog?]
|
363
378
|
end
|
364
379
|
```
|
365
380
|
|
366
381
|
If you want to provide guards for all transitions within an event, you can use event guards
|
367
382
|
|
368
383
|
```ruby
|
369
|
-
event :sleep, :
|
370
|
-
transitions :
|
371
|
-
transitions :
|
384
|
+
event :sleep, guards: [:walked_the_dog?] do
|
385
|
+
transitions from: :running, to: :sleeping, guards: [:cleaning_needed?]
|
386
|
+
transitions from: :cleaning, to: :sleeping
|
372
387
|
end
|
373
388
|
```
|
374
389
|
|
@@ -376,15 +391,30 @@ If you prefer a more Ruby-like guard syntax, you can use `if` and `unless` as we
|
|
376
391
|
|
377
392
|
```ruby
|
378
393
|
event :clean do
|
379
|
-
transitions :
|
394
|
+
transitions from: :running, to: :cleaning, if: :cleaning_needed?
|
380
395
|
end
|
381
396
|
|
382
397
|
event :sleep do
|
383
|
-
transitions :
|
398
|
+
transitions from: :running, to: :sleeping, unless: :cleaning_needed?
|
384
399
|
end
|
385
400
|
end
|
386
401
|
```
|
387
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
|
+
```
|
388
418
|
|
389
419
|
### Transitions
|
390
420
|
|
@@ -397,7 +427,7 @@ class Job
|
|
397
427
|
include AASM
|
398
428
|
|
399
429
|
aasm do
|
400
|
-
state :stage1, :
|
430
|
+
state :stage1, initial: true
|
401
431
|
state :stage2
|
402
432
|
state :stage3
|
403
433
|
state :completed
|
@@ -418,40 +448,67 @@ job.stage1_completed
|
|
418
448
|
job.aasm.current_state # stage3
|
419
449
|
```
|
420
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
|
+
```
|
421
478
|
|
422
479
|
### Multiple state machines per class
|
423
480
|
|
424
481
|
Multiple state machines per class are supported. Be aware though that _AASM_ has been
|
425
|
-
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.
|
426
483
|
|
427
484
|
```ruby
|
428
485
|
class SimpleMultipleExample
|
429
486
|
include AASM
|
430
|
-
aasm(:move) do
|
431
|
-
state :standing, :
|
487
|
+
aasm(:move, column: 'move_state') do
|
488
|
+
state :standing, initial: true
|
432
489
|
state :walking
|
433
490
|
state :running
|
434
491
|
|
435
492
|
event :walk do
|
436
|
-
transitions :
|
493
|
+
transitions from: :standing, to: :walking
|
437
494
|
end
|
438
495
|
event :run do
|
439
|
-
transitions :
|
496
|
+
transitions from: [:standing, :walking], to: :running
|
440
497
|
end
|
441
498
|
event :hold do
|
442
|
-
transitions :
|
499
|
+
transitions from: [:walking, :running], to: :standing
|
443
500
|
end
|
444
501
|
end
|
445
502
|
|
446
|
-
aasm(:work) do
|
447
|
-
state :sleeping, :
|
503
|
+
aasm(:work, column: 'work_state') do
|
504
|
+
state :sleeping, initial: true
|
448
505
|
state :processing
|
449
506
|
|
450
507
|
event :start do
|
451
|
-
transitions :
|
508
|
+
transitions from: :sleeping, to: :processing
|
452
509
|
end
|
453
510
|
event :stop do
|
454
|
-
transitions :
|
511
|
+
transitions from: :processing, to: :sleeping
|
455
512
|
end
|
456
513
|
end
|
457
514
|
end
|
@@ -460,13 +517,13 @@ simple = SimpleMultipleExample.new
|
|
460
517
|
|
461
518
|
simple.aasm(:move).current_state
|
462
519
|
# => :standing
|
463
|
-
simple.aasm(:work).
|
520
|
+
simple.aasm(:work).current_state
|
464
521
|
# => :sleeping
|
465
522
|
|
466
523
|
simple.start
|
467
524
|
simple.aasm(:move).current_state
|
468
525
|
# => :standing
|
469
|
-
simple.aasm(:work).
|
526
|
+
simple.aasm(:work).current_state
|
470
527
|
# => :processing
|
471
528
|
|
472
529
|
```
|
@@ -484,28 +541,28 @@ Alternatively, you can provide a namespace for each state machine:
|
|
484
541
|
class NamespacedMultipleExample
|
485
542
|
include AASM
|
486
543
|
aasm(:status) do
|
487
|
-
state :unapproved, :
|
544
|
+
state :unapproved, initial: true
|
488
545
|
state :approved
|
489
546
|
|
490
547
|
event :approve do
|
491
|
-
transitions :
|
548
|
+
transitions from: :unapproved, to: :approved
|
492
549
|
end
|
493
550
|
|
494
551
|
event :unapprove do
|
495
|
-
transitions :
|
552
|
+
transitions from: :approved, to: :unapproved
|
496
553
|
end
|
497
554
|
end
|
498
555
|
|
499
556
|
aasm(:review_status, namespace: :review) do
|
500
|
-
state :unapproved, :
|
557
|
+
state :unapproved, initial: true
|
501
558
|
state :approved
|
502
559
|
|
503
560
|
event :approve do
|
504
|
-
transitions :
|
561
|
+
transitions from: :unapproved, to: :approved
|
505
562
|
end
|
506
563
|
|
507
564
|
event :unapprove do
|
508
|
-
transitions :
|
565
|
+
transitions from: :approved, to: :unapproved
|
509
566
|
end
|
510
567
|
end
|
511
568
|
end
|
@@ -537,26 +594,26 @@ class Example
|
|
537
594
|
include AASM
|
538
595
|
|
539
596
|
aasm(:work) do
|
540
|
-
state :sleeping, :
|
597
|
+
state :sleeping, initial: true
|
541
598
|
state :processing
|
542
599
|
|
543
600
|
event :start do
|
544
|
-
transitions :
|
601
|
+
transitions from: :sleeping, to: :processing
|
545
602
|
end
|
546
603
|
event :stop do
|
547
|
-
transitions :
|
604
|
+
transitions from: :processing, to: :sleeping
|
548
605
|
end
|
549
606
|
end
|
550
607
|
|
551
608
|
aasm(:question) do
|
552
|
-
state :answered, :
|
609
|
+
state :answered, initial: true
|
553
610
|
state :asked
|
554
611
|
|
555
|
-
event :ask, :
|
556
|
-
transitions :
|
612
|
+
event :ask, binding_event: :start do
|
613
|
+
transitions from: :answered, to: :asked
|
557
614
|
end
|
558
|
-
event :answer, :
|
559
|
-
transitions :
|
615
|
+
event :answer, binding_event: :stop do
|
616
|
+
transitions from: :asked, to: :answered
|
560
617
|
end
|
561
618
|
end
|
562
619
|
end
|
@@ -602,7 +659,7 @@ class CustomAASMBase < AASM::Base
|
|
602
659
|
# A custom transiton that we want available across many AASM models.
|
603
660
|
def count_transitions!
|
604
661
|
klass.class_eval do
|
605
|
-
aasm :
|
662
|
+
aasm with_klass: CustomAASMBase do
|
606
663
|
after_all_transitions :increment_transition_count
|
607
664
|
end
|
608
665
|
end
|
@@ -639,19 +696,19 @@ class SimpleCustomExample
|
|
639
696
|
include AASM
|
640
697
|
|
641
698
|
# Let's build an AASM state machine with our custom class.
|
642
|
-
aasm :
|
699
|
+
aasm with_klass: CustomAASMBase do
|
643
700
|
requires_guards!
|
644
701
|
count_transitions!
|
645
702
|
|
646
|
-
state :initialised, :
|
703
|
+
state :initialised, initial: true
|
647
704
|
state :filled_out
|
648
705
|
state :authorised
|
649
706
|
|
650
707
|
event :fill_out do
|
651
|
-
transitions :
|
708
|
+
transitions from: :initialised, to: :filled_out, guard: :fillable?
|
652
709
|
end
|
653
710
|
event :authorise do
|
654
|
-
transitions :
|
711
|
+
transitions from: :filled_out, to: :authorised, guard: :authorizable?
|
655
712
|
end
|
656
713
|
end
|
657
714
|
end
|
@@ -663,20 +720,22 @@ end
|
|
663
720
|
AASM comes with support for ActiveRecord and allows automatic persisting of the object's
|
664
721
|
state in the database.
|
665
722
|
|
723
|
+
Add `gem 'after_commit_everywhere', '~> 1.0'` to your Gemfile.
|
724
|
+
|
666
725
|
```ruby
|
667
726
|
class Job < ActiveRecord::Base
|
668
727
|
include AASM
|
669
728
|
|
670
729
|
aasm do # default column: aasm_state
|
671
|
-
state :sleeping, :
|
730
|
+
state :sleeping, initial: true
|
672
731
|
state :running
|
673
732
|
|
674
733
|
event :run do
|
675
|
-
transitions :
|
734
|
+
transitions from: :sleeping, to: :running
|
676
735
|
end
|
677
736
|
|
678
737
|
event :sleep do
|
679
|
-
transitions :
|
738
|
+
transitions from: :running, to: :sleeping
|
680
739
|
end
|
681
740
|
end
|
682
741
|
|
@@ -699,7 +758,7 @@ job.aasm.fire!(:run) # saved
|
|
699
758
|
|
700
759
|
Saving includes running all validations on the `Job` class. If
|
701
760
|
`whiny_persistence` flag is set to `true`, exception is raised in case of
|
702
|
-
failure. If `whiny_persistence` flag is set to false
|
761
|
+
failure. If `whiny_persistence` flag is set to `false`, methods with a bang return
|
703
762
|
`true` if the state transition is successful or `false` if an error occurs.
|
704
763
|
|
705
764
|
If you want make sure the state gets saved without running validations (and
|
@@ -711,22 +770,30 @@ be updated in the database (just like ActiveRecord `update_column` is working).
|
|
711
770
|
class Job < ActiveRecord::Base
|
712
771
|
include AASM
|
713
772
|
|
714
|
-
aasm :
|
715
|
-
state :sleeping, :
|
773
|
+
aasm skip_validation_on_save: true do
|
774
|
+
state :sleeping, initial: true
|
716
775
|
state :running
|
717
776
|
|
718
777
|
event :run do
|
719
|
-
transitions :
|
778
|
+
transitions from: :sleeping, to: :running
|
720
779
|
end
|
721
780
|
|
722
781
|
event :sleep do
|
723
|
-
transitions :
|
782
|
+
transitions from: :running, to: :sleeping
|
724
783
|
end
|
725
784
|
end
|
726
785
|
|
727
786
|
end
|
728
787
|
```
|
729
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
|
+
|
730
797
|
If you want to make sure that the _AASM_ column for storing the state is not directly assigned,
|
731
798
|
configure _AASM_ to not allow direct assignment, like this:
|
732
799
|
|
@@ -734,12 +801,12 @@ configure _AASM_ to not allow direct assignment, like this:
|
|
734
801
|
class Job < ActiveRecord::Base
|
735
802
|
include AASM
|
736
803
|
|
737
|
-
aasm :
|
738
|
-
state :sleeping, :
|
804
|
+
aasm no_direct_assignment: true do
|
805
|
+
state :sleeping, initial: true
|
739
806
|
state :running
|
740
807
|
|
741
808
|
event :run do
|
742
|
-
transitions :
|
809
|
+
transitions from: :sleeping, to: :running
|
743
810
|
end
|
744
811
|
end
|
745
812
|
|
@@ -755,6 +822,37 @@ job.aasm_state = :running # => raises AASM::NoDirectAssignmentError
|
|
755
822
|
job.aasm_state # => 'sleeping'
|
756
823
|
```
|
757
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
|
+
|
758
856
|
#### ActiveRecord enums
|
759
857
|
|
760
858
|
You can use
|
@@ -770,8 +868,8 @@ class Job < ActiveRecord::Base
|
|
770
868
|
running: 99
|
771
869
|
}
|
772
870
|
|
773
|
-
aasm :
|
774
|
-
state :sleeping, :
|
871
|
+
aasm column: :state, enum: true do
|
872
|
+
state :sleeping, initial: true
|
775
873
|
state :running
|
776
874
|
end
|
777
875
|
end
|
@@ -870,7 +968,7 @@ class Job < ActiveRecord::Base
|
|
870
968
|
include AASM
|
871
969
|
|
872
970
|
aasm do
|
873
|
-
state :sleeping, :
|
971
|
+
state :sleeping, initial: true
|
874
972
|
state :running
|
875
973
|
state :cleaning
|
876
974
|
end
|
@@ -899,8 +997,8 @@ defining the `AASM` states, like this:
|
|
899
997
|
class Job < ActiveRecord::Base
|
900
998
|
include AASM
|
901
999
|
|
902
|
-
aasm :
|
903
|
-
state :sleeping, :
|
1000
|
+
aasm create_scopes: false do
|
1001
|
+
state :sleeping, initial: true
|
904
1002
|
state :running
|
905
1003
|
state :cleaning
|
906
1004
|
end
|
@@ -933,11 +1031,11 @@ class Job < ActiveRecord::Base
|
|
933
1031
|
include AASM
|
934
1032
|
|
935
1033
|
aasm do
|
936
|
-
state :sleeping, :
|
1034
|
+
state :sleeping, initial: true
|
937
1035
|
state :running
|
938
1036
|
|
939
|
-
event :run, :
|
940
|
-
transitions :
|
1037
|
+
event :run, after_commit: :notify_about_running_job do
|
1038
|
+
transitions from: :sleeping, to: :running
|
941
1039
|
end
|
942
1040
|
end
|
943
1041
|
|
@@ -959,18 +1057,24 @@ job.run
|
|
959
1057
|
job.save! #notify_about_running_job is not run
|
960
1058
|
```
|
961
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
|
+
|
962
1066
|
If you want to encapsulate state changes within an own transaction, the behavior
|
963
1067
|
of this nested transaction might be confusing. Take a look at
|
964
1068
|
[ActiveRecord Nested Transactions](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)
|
965
1069
|
if you want to know more about this. Nevertheless, AASM by default requires a new transaction
|
966
|
-
`transaction(:
|
1070
|
+
`transaction(requires_new: true)`. You can override this behavior by changing
|
967
1071
|
the configuration
|
968
1072
|
|
969
1073
|
```ruby
|
970
1074
|
class Job < ActiveRecord::Base
|
971
1075
|
include AASM
|
972
1076
|
|
973
|
-
aasm :
|
1077
|
+
aasm requires_new_transaction: false do
|
974
1078
|
...
|
975
1079
|
end
|
976
1080
|
|
@@ -978,9 +1082,9 @@ class Job < ActiveRecord::Base
|
|
978
1082
|
end
|
979
1083
|
```
|
980
1084
|
|
981
|
-
which then leads to `transaction(:
|
1085
|
+
which then leads to `transaction(requires_new: false)`, the Rails default.
|
982
1086
|
|
983
|
-
Additionally, if you do not want any of your
|
1087
|
+
Additionally, if you do not want any of your ActiveRecord actions to be
|
984
1088
|
wrapped in a transaction, you can specify the `use_transactions` flag. This can
|
985
1089
|
be useful if you want want to persist things to the database that happen as a
|
986
1090
|
result of a transaction or callback, even when some error occurs. The
|
@@ -990,7 +1094,7 @@ result of a transaction or callback, even when some error occurs. The
|
|
990
1094
|
class Job < ActiveRecord::Base
|
991
1095
|
include AASM
|
992
1096
|
|
993
|
-
aasm :
|
1097
|
+
aasm use_transactions: false do
|
994
1098
|
...
|
995
1099
|
end
|
996
1100
|
|
@@ -1000,7 +1104,7 @@ end
|
|
1000
1104
|
|
1001
1105
|
### Pessimistic Locking
|
1002
1106
|
|
1003
|
-
AASM supports [
|
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.
|
1004
1108
|
|
1005
1109
|
| Option | Purpose |
|
1006
1110
|
| ------ | ------- |
|
@@ -1013,7 +1117,7 @@ AASM supports [Active Record pessimistic locking via `with_lock`](http://api.rub
|
|
1013
1117
|
class Job < ActiveRecord::Base
|
1014
1118
|
include AASM
|
1015
1119
|
|
1016
|
-
aasm :
|
1120
|
+
aasm requires_lock: true do
|
1017
1121
|
...
|
1018
1122
|
end
|
1019
1123
|
|
@@ -1025,7 +1129,7 @@ end
|
|
1025
1129
|
class Job < ActiveRecord::Base
|
1026
1130
|
include AASM
|
1027
1131
|
|
1028
|
-
aasm :
|
1132
|
+
aasm requires_lock: 'FOR UPDATE NOWAIT' do
|
1029
1133
|
...
|
1030
1134
|
end
|
1031
1135
|
|
@@ -1043,18 +1147,21 @@ this by defining your favorite column name, using `:column` like this:
|
|
1043
1147
|
class Job < ActiveRecord::Base
|
1044
1148
|
include AASM
|
1045
1149
|
|
1046
|
-
aasm :
|
1150
|
+
aasm column: :my_state do
|
1047
1151
|
...
|
1048
1152
|
end
|
1049
1153
|
|
1050
|
-
aasm :another_state_machine, column:
|
1154
|
+
aasm :another_state_machine, column: :second_state do
|
1051
1155
|
...
|
1052
1156
|
end
|
1053
1157
|
end
|
1054
1158
|
```
|
1055
1159
|
|
1056
1160
|
Whatever column name is used, make sure to add a migration to provide this column
|
1057
|
-
(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.
|
1058
1165
|
|
1059
1166
|
```ruby
|
1060
1167
|
class AddJobState < ActiveRecord::Migration
|
@@ -1068,6 +1175,13 @@ class AddJobState < ActiveRecord::Migration
|
|
1068
1175
|
end
|
1069
1176
|
```
|
1070
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
|
+
|
1071
1185
|
### Inspection
|
1072
1186
|
|
1073
1187
|
AASM supports query methods for states and events
|
@@ -1079,19 +1193,19 @@ class Job
|
|
1079
1193
|
include AASM
|
1080
1194
|
|
1081
1195
|
aasm do
|
1082
|
-
state :sleeping, :
|
1196
|
+
state :sleeping, initial: true
|
1083
1197
|
state :running, :cleaning
|
1084
1198
|
|
1085
1199
|
event :run do
|
1086
|
-
transitions :
|
1200
|
+
transitions from: :sleeping, to: :running
|
1087
1201
|
end
|
1088
1202
|
|
1089
1203
|
event :clean do
|
1090
|
-
transitions :
|
1204
|
+
transitions from: :running, to: :cleaning, guard: :cleaning_needed?
|
1091
1205
|
end
|
1092
1206
|
|
1093
1207
|
event :sleep do
|
1094
|
-
transitions :
|
1208
|
+
transitions from: [:running, :cleaning], to: :sleeping
|
1095
1209
|
end
|
1096
1210
|
end
|
1097
1211
|
|
@@ -1109,15 +1223,19 @@ Job.aasm.states.map(&:name)
|
|
1109
1223
|
job = Job.new
|
1110
1224
|
|
1111
1225
|
# show all permitted states (from initial state)
|
1112
|
-
job.aasm.states(:
|
1226
|
+
job.aasm.states(permitted: true).map(&:name)
|
1113
1227
|
#=> [:running]
|
1114
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
|
+
|
1115
1233
|
job.run
|
1116
|
-
job.aasm.states(:
|
1234
|
+
job.aasm.states(permitted: true).map(&:name)
|
1117
1235
|
#=> [:sleeping]
|
1118
1236
|
|
1119
1237
|
# show all non permitted states
|
1120
|
-
job.aasm.states(:
|
1238
|
+
job.aasm.states(permitted: false).map(&:name)
|
1121
1239
|
#=> [:cleaning]
|
1122
1240
|
|
1123
1241
|
# show all possible (triggerable) events from the current state
|
@@ -1125,23 +1243,23 @@ job.aasm.events.map(&:name)
|
|
1125
1243
|
#=> [:clean, :sleep]
|
1126
1244
|
|
1127
1245
|
# show all permitted events
|
1128
|
-
job.aasm.events(:
|
1246
|
+
job.aasm.events(permitted: true).map(&:name)
|
1129
1247
|
#=> [:sleep]
|
1130
1248
|
|
1131
1249
|
# show all non permitted events
|
1132
|
-
job.aasm.events(:
|
1250
|
+
job.aasm.events(permitted: false).map(&:name)
|
1133
1251
|
#=> [:clean]
|
1134
1252
|
|
1135
1253
|
# show all possible events except a specific one
|
1136
|
-
job.aasm.events(:
|
1254
|
+
job.aasm.events(reject: :sleep).map(&:name)
|
1137
1255
|
#=> [:clean]
|
1138
1256
|
|
1139
1257
|
# list states for select
|
1140
1258
|
Job.aasm.states_for_select
|
1141
|
-
|
1259
|
+
#=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
|
1142
1260
|
|
1143
1261
|
# show permitted states with guard parameter
|
1144
|
-
job.aasm.states({:
|
1262
|
+
job.aasm.states({permitted: true}, guard_parameter).map(&:name)
|
1145
1263
|
```
|
1146
1264
|
|
1147
1265
|
|
@@ -1154,7 +1272,7 @@ use
|
|
1154
1272
|
class Job
|
1155
1273
|
include AASM
|
1156
1274
|
|
1157
|
-
aasm :
|
1275
|
+
aasm logger: Rails.logger do
|
1158
1276
|
...
|
1159
1277
|
end
|
1160
1278
|
end
|
@@ -1178,7 +1296,15 @@ the 'instance method symbol / string' way whenever possible when defining guardi
|
|
1178
1296
|
|
1179
1297
|
#### RSpec
|
1180
1298
|
|
1181
|
-
AASM provides some matchers for [RSpec](http://rspec.info):
|
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:
|
1182
1308
|
|
1183
1309
|
```ruby
|
1184
1310
|
# classes with only the default state machine
|
@@ -1191,7 +1317,7 @@ expect(job).to allow_event :run
|
|
1191
1317
|
expect(job).to_not allow_event :clean
|
1192
1318
|
expect(job).to allow_transition_to(:running)
|
1193
1319
|
expect(job).to_not allow_transition_to(:cleaning)
|
1194
|
-
# on_event also accept arguments
|
1320
|
+
# on_event also accept multiple arguments
|
1195
1321
|
expect(job).to transition_from(:sleeping).to(:running).on_event(:run, :defragmentation)
|
1196
1322
|
|
1197
1323
|
# classes with multiple state machine
|
@@ -1225,6 +1351,9 @@ AASM provides assertions and rspec-like expectations for [Minitest](https://gith
|
|
1225
1351
|
|
1226
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`.
|
1227
1353
|
|
1354
|
+
|
1355
|
+
##### Examples Of Usage (Minitest):
|
1356
|
+
|
1228
1357
|
Add `require 'aasm/minitest'` to your `test_helper.rb` file and use them like this:
|
1229
1358
|
|
1230
1359
|
```ruby
|
@@ -1332,7 +1461,7 @@ After installing AASM you can run generator:
|
|
1332
1461
|
```
|
1333
1462
|
Replace NAME with the Model name, COLUMN_NAME is optional(default is 'aasm_state').
|
1334
1463
|
This will create a model (if one does not exist) and configure it with aasm block.
|
1335
|
-
For
|
1464
|
+
For ActiveRecord orm a migration file is added to add aasm state column to table.
|
1336
1465
|
|
1337
1466
|
### Docker
|
1338
1467
|
|
@@ -1362,6 +1491,12 @@ Feel free to
|
|
1362
1491
|
* [Anil Maurya](http://github.com/anilmaurya) (since 2016)
|
1363
1492
|
|
1364
1493
|
|
1494
|
+
|
1495
|
+
## Stargazers over time
|
1496
|
+
|
1497
|
+
[![Stargazers over time](https://starchart.cc/aasm/aasm.svg)](https://starchart.cc/aasm/aasm)
|
1498
|
+
|
1499
|
+
|
1365
1500
|
## [Contributing](CONTRIBUTING.md)
|
1366
1501
|
|
1367
1502
|
## Warranty ##
|