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.
- checksums.yaml +5 -5
- data/README.md +243 -118
- 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 -9
- 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 +25 -5
- 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 -377
- 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 -44
- 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 -17
- 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 -735
- 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
|
[](http://badge.fury.io/rb/aasm)
|
4
4
|
[](https://travis-ci.org/aasm/aasm)
|
5
|
-
[](https://gemnasium.com/aasm/aasm)
|
6
5
|
[](https://codeclimate.com/github/aasm/aasm)
|
6
|
+
[](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
|
@@ -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, :
|
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, :
|
149
|
+
event :run, after: :notify_somebody do
|
158
150
|
before do
|
159
151
|
log('Preparing to run')
|
160
152
|
end
|
161
153
|
|
162
|
-
transitions :
|
163
|
-
transitions :
|
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 :
|
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
|
-
|
216
|
+
#### Parameters
|
217
|
+
You can pass parameters to events:
|
225
218
|
|
226
219
|
```ruby
|
227
220
|
job = Job.new
|
228
|
-
job.run(:
|
221
|
+
job.run(:defragmentation)
|
229
222
|
```
|
230
223
|
|
231
|
-
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
|
232
229
|
|
233
|
-
|
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`
|
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, :
|
331
|
+
state :idle, initial: true
|
327
332
|
state :cleaning
|
328
333
|
|
329
334
|
event :clean do
|
330
|
-
transitions :
|
335
|
+
transitions from: :idle, to: :cleaning, guard: :cleaning_needed?
|
331
336
|
end
|
332
337
|
|
333
338
|
event :clean_if_needed do
|
334
|
-
transitions :
|
339
|
+
transitions from: :idle, to: :cleaning do
|
335
340
|
guard do
|
336
341
|
cleaning_needed?
|
337
342
|
end
|
338
343
|
end
|
339
|
-
transitions :
|
344
|
+
transitions from: :idle, to: :idle
|
340
345
|
end
|
341
346
|
|
342
347
|
event :clean_if_dirty do
|
343
|
-
transitions :
|
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) # =>
|
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 :
|
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, :
|
380
|
-
transitions :
|
381
|
-
transitions :
|
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 :
|
394
|
+
transitions from: :running, to: :cleaning, if: :cleaning_needed?
|
390
395
|
end
|
391
396
|
|
392
397
|
event :sleep do
|
393
|
-
transitions :
|
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, :
|
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, :
|
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 :
|
493
|
+
transitions from: :standing, to: :walking
|
447
494
|
end
|
448
495
|
event :run do
|
449
|
-
transitions :
|
496
|
+
transitions from: [:standing, :walking], to: :running
|
450
497
|
end
|
451
498
|
event :hold do
|
452
|
-
transitions :
|
499
|
+
transitions from: [:walking, :running], to: :standing
|
453
500
|
end
|
454
501
|
end
|
455
502
|
|
456
|
-
aasm(:work) do
|
457
|
-
state :sleeping, :
|
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 :
|
508
|
+
transitions from: :sleeping, to: :processing
|
462
509
|
end
|
463
510
|
event :stop do
|
464
|
-
transitions :
|
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).
|
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).
|
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, :
|
544
|
+
state :unapproved, initial: true
|
498
545
|
state :approved
|
499
546
|
|
500
547
|
event :approve do
|
501
|
-
transitions :
|
548
|
+
transitions from: :unapproved, to: :approved
|
502
549
|
end
|
503
550
|
|
504
551
|
event :unapprove do
|
505
|
-
transitions :
|
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, :
|
557
|
+
state :unapproved, initial: true
|
511
558
|
state :approved
|
512
559
|
|
513
560
|
event :approve do
|
514
|
-
transitions :
|
561
|
+
transitions from: :unapproved, to: :approved
|
515
562
|
end
|
516
563
|
|
517
564
|
event :unapprove do
|
518
|
-
transitions :
|
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, :
|
597
|
+
state :sleeping, initial: true
|
551
598
|
state :processing
|
552
599
|
|
553
600
|
event :start do
|
554
|
-
transitions :
|
601
|
+
transitions from: :sleeping, to: :processing
|
555
602
|
end
|
556
603
|
event :stop do
|
557
|
-
transitions :
|
604
|
+
transitions from: :processing, to: :sleeping
|
558
605
|
end
|
559
606
|
end
|
560
607
|
|
561
608
|
aasm(:question) do
|
562
|
-
state :answered, :
|
609
|
+
state :answered, initial: true
|
563
610
|
state :asked
|
564
611
|
|
565
|
-
event :ask, :
|
566
|
-
transitions :
|
612
|
+
event :ask, binding_event: :start do
|
613
|
+
transitions from: :answered, to: :asked
|
567
614
|
end
|
568
|
-
event :answer, :
|
569
|
-
transitions :
|
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 :
|
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 :
|
699
|
+
aasm with_klass: CustomAASMBase do
|
653
700
|
requires_guards!
|
654
701
|
count_transitions!
|
655
702
|
|
656
|
-
state :initialised, :
|
703
|
+
state :initialised, initial: true
|
657
704
|
state :filled_out
|
658
705
|
state :authorised
|
659
706
|
|
660
707
|
event :fill_out do
|
661
|
-
transitions :
|
708
|
+
transitions from: :initialised, to: :filled_out, guard: :fillable?
|
662
709
|
end
|
663
710
|
event :authorise do
|
664
|
-
transitions :
|
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, :
|
730
|
+
state :sleeping, initial: true
|
682
731
|
state :running
|
683
732
|
|
684
733
|
event :run do
|
685
|
-
transitions :
|
734
|
+
transitions from: :sleeping, to: :running
|
686
735
|
end
|
687
736
|
|
688
737
|
event :sleep do
|
689
|
-
transitions :
|
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
|
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 :
|
725
|
-
state :sleeping, :
|
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 :
|
778
|
+
transitions from: :sleeping, to: :running
|
730
779
|
end
|
731
780
|
|
732
781
|
event :sleep do
|
733
|
-
transitions :
|
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 :
|
748
|
-
state :sleeping, :
|
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 :
|
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 :
|
784
|
-
state :sleeping, :
|
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, :
|
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 :
|
913
|
-
state :sleeping, :
|
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, :
|
1034
|
+
state :sleeping, initial: true
|
947
1035
|
state :running
|
948
1036
|
|
949
|
-
event :run, :
|
950
|
-
transitions :
|
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(:
|
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 :
|
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(:
|
1085
|
+
which then leads to `transaction(requires_new: false)`, the Rails default.
|
992
1086
|
|
993
|
-
Additionally, if you do not want any of your
|
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 :
|
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 [
|
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 :
|
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 :
|
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 :
|
1150
|
+
aasm column: :my_state do
|
1057
1151
|
...
|
1058
1152
|
end
|
1059
1153
|
|
1060
|
-
aasm :another_state_machine, column:
|
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, :
|
1196
|
+
state :sleeping, initial: true
|
1093
1197
|
state :running, :cleaning
|
1094
1198
|
|
1095
1199
|
event :run do
|
1096
|
-
transitions :
|
1200
|
+
transitions from: :sleeping, to: :running
|
1097
1201
|
end
|
1098
1202
|
|
1099
1203
|
event :clean do
|
1100
|
-
transitions :
|
1204
|
+
transitions from: :running, to: :cleaning, guard: :cleaning_needed?
|
1101
1205
|
end
|
1102
1206
|
|
1103
1207
|
event :sleep do
|
1104
|
-
transitions :
|
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(:
|
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(:
|
1234
|
+
job.aasm.states(permitted: true).map(&:name)
|
1127
1235
|
#=> [:sleeping]
|
1128
1236
|
|
1129
1237
|
# show all non permitted states
|
1130
|
-
job.aasm.states(:
|
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(:
|
1246
|
+
job.aasm.events(permitted: true).map(&:name)
|
1139
1247
|
#=> [:sleep]
|
1140
1248
|
|
1141
1249
|
# show all non permitted events
|
1142
|
-
job.aasm.events(:
|
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(:
|
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
|
-
|
1259
|
+
#=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
|
1152
1260
|
|
1153
1261
|
# show permitted states with guard parameter
|
1154
|
-
job.aasm.states({:
|
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 :
|
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):
|
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
|
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
|
+
[](https://starchart.cc/aasm/aasm)
|
1498
|
+
|
1499
|
+
|
1375
1500
|
## [Contributing](CONTRIBUTING.md)
|
1376
1501
|
|
1377
1502
|
## Warranty ##
|