aasm 2.1.1 → 5.2.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 +7 -0
- data/.document +6 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +20 -0
- data/.travis.yml +82 -0
- data/API +34 -0
- data/Appraisals +67 -0
- data/CHANGELOG.md +453 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +24 -0
- data/Dockerfile +44 -0
- data/Gemfile +6 -0
- data/Gemfile.lock_old +151 -0
- data/HOWTO +12 -0
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/PLANNED_CHANGES.md +11 -0
- data/README.md +1524 -0
- data/README_FROM_VERSION_3_TO_4.md +240 -0
- data/Rakefile +20 -84
- data/TESTING.md +25 -0
- data/aasm.gemspec +37 -0
- data/docker-compose.yml +40 -0
- data/gemfiles/norails.gemfile +10 -0
- data/gemfiles/rails_4.2.gemfile +17 -0
- data/gemfiles/rails_4.2_mongoid_5.gemfile +12 -0
- data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +14 -0
- data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +14 -0
- data/gemfiles/rails_5.2.gemfile +14 -0
- data/lib/aasm/aasm.rb +160 -137
- data/lib/aasm/base.rb +290 -0
- data/lib/aasm/configuration.rb +48 -0
- data/lib/aasm/core/event.rb +177 -0
- data/lib/aasm/core/invoker.rb +129 -0
- data/lib/aasm/core/invokers/base_invoker.rb +75 -0
- data/lib/aasm/core/invokers/class_invoker.rb +52 -0
- data/lib/aasm/core/invokers/literal_invoker.rb +47 -0
- data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
- data/lib/aasm/core/state.rb +91 -0
- data/lib/aasm/core/transition.rb +83 -0
- data/lib/aasm/dsl_helper.rb +32 -0
- data/lib/aasm/errors.rb +21 -0
- data/lib/aasm/instance_base.rb +133 -0
- data/lib/aasm/localizer.rb +64 -0
- data/lib/aasm/minitest/allow_event.rb +13 -0
- data/lib/aasm/minitest/allow_transition_to.rb +13 -0
- data/lib/aasm/minitest/have_state.rb +13 -0
- data/lib/aasm/minitest/transition_from.rb +21 -0
- data/lib/aasm/minitest.rb +5 -0
- data/lib/aasm/minitest_spec.rb +15 -0
- data/lib/aasm/persistence/active_record_persistence.rb +108 -173
- data/lib/aasm/persistence/base.rb +89 -0
- data/lib/aasm/persistence/core_data_query_persistence.rb +94 -0
- data/lib/aasm/persistence/dynamoid_persistence.rb +92 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +126 -0
- data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
- data/lib/aasm/persistence/orm.rb +154 -0
- data/lib/aasm/persistence/plain_persistence.rb +26 -0
- data/lib/aasm/persistence/redis_persistence.rb +112 -0
- data/lib/aasm/persistence/sequel_persistence.rb +83 -0
- data/lib/aasm/persistence.rb +48 -10
- data/lib/aasm/rspec/allow_event.rb +26 -0
- data/lib/aasm/rspec/allow_transition_to.rb +26 -0
- data/lib/aasm/rspec/have_state.rb +22 -0
- data/lib/aasm/rspec/transition_from.rb +36 -0
- data/lib/aasm/rspec.rb +5 -0
- data/lib/aasm/state_machine.rb +40 -22
- data/lib/aasm/state_machine_store.rb +76 -0
- data/lib/aasm/version.rb +3 -0
- data/lib/aasm.rb +21 -1
- data/lib/generators/aasm/aasm_generator.rb +16 -0
- data/lib/generators/aasm/orm_helpers.rb +41 -0
- data/lib/generators/active_record/aasm_generator.rb +40 -0
- data/lib/generators/active_record/templates/migration.rb +8 -0
- data/lib/generators/active_record/templates/migration_existing.rb +5 -0
- data/lib/generators/mongoid/aasm_generator.rb +28 -0
- data/lib/generators/nobrainer/aasm_generator.rb +28 -0
- data/lib/motion-aasm.rb +37 -0
- data/spec/database.rb +57 -0
- data/spec/database.yml +3 -0
- data/spec/en.yml +9 -0
- data/spec/generators/active_record_generator_spec.rb +53 -0
- data/spec/generators/mongoid_generator_spec.rb +31 -0
- data/spec/generators/no_brainer_generator_spec.rb +29 -0
- data/spec/localizer_test_model_deprecated_style.yml +13 -0
- data/spec/localizer_test_model_new_style.yml +11 -0
- data/spec/models/active_record/active_record_callback.rb +93 -0
- data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +25 -0
- data/spec/models/active_record/complex_active_record_example.rb +37 -0
- data/spec/models/active_record/derivate_new_dsl.rb +7 -0
- data/spec/models/active_record/false_state.rb +35 -0
- data/spec/models/active_record/gate.rb +39 -0
- data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
- data/spec/models/active_record/invalid_persistor.rb +29 -0
- data/spec/models/active_record/localizer_test_model.rb +42 -0
- data/spec/models/active_record/namespaced.rb +16 -0
- data/spec/models/active_record/no_direct_assignment.rb +21 -0
- data/spec/models/active_record/no_scope.rb +21 -0
- data/spec/models/active_record/persisted_state.rb +12 -0
- data/spec/models/active_record/person.rb +23 -0
- data/spec/models/active_record/provided_and_persisted_state.rb +24 -0
- data/spec/models/active_record/reader.rb +7 -0
- data/spec/models/active_record/readme_job.rb +21 -0
- data/spec/models/active_record/silent_persistor.rb +29 -0
- data/spec/models/active_record/simple_new_dsl.rb +32 -0
- data/spec/models/active_record/thief.rb +29 -0
- data/spec/models/active_record/timestamp_example.rb +16 -0
- data/spec/models/active_record/transactor.rb +124 -0
- data/spec/models/active_record/transient.rb +6 -0
- data/spec/models/active_record/validator.rb +118 -0
- data/spec/models/active_record/with_enum.rb +39 -0
- data/spec/models/active_record/with_enum_without_column.rb +38 -0
- data/spec/models/active_record/with_false_enum.rb +31 -0
- data/spec/models/active_record/with_true_enum.rb +39 -0
- data/spec/models/active_record/work.rb +3 -0
- data/spec/models/active_record/worker.rb +2 -0
- data/spec/models/active_record/writer.rb +6 -0
- data/spec/models/basic_two_state_machines_example.rb +25 -0
- data/spec/models/callbacks/basic.rb +98 -0
- data/spec/models/callbacks/basic_multiple.rb +75 -0
- data/spec/models/callbacks/guard_within_block.rb +67 -0
- data/spec/models/callbacks/guard_within_block_multiple.rb +66 -0
- data/spec/models/callbacks/multiple_transitions_transition_guard.rb +66 -0
- data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +65 -0
- data/spec/models/callbacks/private_method.rb +44 -0
- data/spec/models/callbacks/private_method_multiple.rb +44 -0
- data/spec/models/callbacks/with_args.rb +62 -0
- data/spec/models/callbacks/with_args_multiple.rb +61 -0
- data/spec/models/callbacks/with_state_arg.rb +34 -0
- data/spec/models/callbacks/with_state_arg_multiple.rb +29 -0
- data/spec/models/complex_example.rb +222 -0
- data/spec/models/conversation.rb +93 -0
- data/spec/models/default_state.rb +12 -0
- data/spec/models/double_definer.rb +21 -0
- data/spec/models/dynamoid/complex_dynamoid_example.rb +37 -0
- data/spec/models/dynamoid/dynamoid_multiple.rb +18 -0
- data/spec/models/dynamoid/dynamoid_simple.rb +18 -0
- data/spec/models/foo.rb +106 -0
- data/spec/models/foo_callback_multiple.rb +45 -0
- data/spec/models/guard_arguments_check.rb +17 -0
- data/spec/models/guard_with_params.rb +24 -0
- data/spec/models/guard_with_params_multiple.rb +18 -0
- data/spec/models/guardian.rb +58 -0
- data/spec/models/guardian_multiple.rb +48 -0
- data/spec/models/guardian_without_from_specified.rb +18 -0
- data/spec/models/initial_state_proc.rb +31 -0
- data/spec/models/mongoid/complex_mongoid_example.rb +37 -0
- data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/mongoid_relationships.rb +26 -0
- data/spec/models/mongoid/no_scope_mongoid.rb +21 -0
- data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/simple_mongoid.rb +23 -0
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +25 -0
- data/spec/models/mongoid/timestamp_example_mongoid.rb +20 -0
- data/spec/models/mongoid/validator_mongoid.rb +100 -0
- data/spec/models/multi_transitioner.rb +34 -0
- data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
- data/spec/models/namespaced_multiple_example.rb +42 -0
- data/spec/models/no_initial_state.rb +25 -0
- data/spec/models/nobrainer/complex_no_brainer_example.rb +36 -0
- data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +39 -0
- data/spec/models/nobrainer/no_scope_no_brainer.rb +21 -0
- data/spec/models/nobrainer/nobrainer_relationships.rb +25 -0
- data/spec/models/nobrainer/silent_persistor_no_brainer.rb +39 -0
- data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +25 -0
- data/spec/models/nobrainer/simple_no_brainer.rb +23 -0
- data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
- data/spec/models/not_auto_loaded/process.rb +21 -0
- data/spec/models/parametrised_event.rb +42 -0
- data/spec/models/parametrised_event_multiple.rb +29 -0
- data/spec/models/process_with_new_dsl.rb +31 -0
- data/spec/models/provided_state.rb +24 -0
- data/spec/models/redis/complex_redis_example.rb +40 -0
- data/spec/models/redis/redis_multiple.rb +20 -0
- data/spec/models/redis/redis_simple.rb +20 -0
- data/spec/models/sequel/complex_sequel_example.rb +46 -0
- data/spec/models/sequel/invalid_persistor.rb +52 -0
- data/spec/models/sequel/sequel_multiple.rb +25 -0
- data/spec/models/sequel/sequel_simple.rb +26 -0
- data/spec/models/sequel/silent_persistor.rb +50 -0
- data/spec/models/sequel/transactor.rb +112 -0
- data/spec/models/sequel/validator.rb +93 -0
- data/spec/models/sequel/worker.rb +12 -0
- data/spec/models/silencer.rb +27 -0
- data/spec/models/simple_custom_example.rb +53 -0
- data/spec/models/simple_example.rb +23 -0
- data/spec/models/simple_example_with_guard_args.rb +17 -0
- data/spec/models/simple_multiple_example.rb +42 -0
- data/spec/models/state_machine_with_failed_event.rb +20 -0
- data/spec/models/states_on_one_line_example.rb +8 -0
- data/spec/models/sub_class.rb +41 -0
- data/spec/models/sub_class_with_more_states.rb +18 -0
- data/spec/models/sub_classing.rb +3 -0
- data/spec/models/super_class.rb +46 -0
- data/spec/models/this_name_better_not_be_in_use.rb +11 -0
- data/spec/models/timestamps_example.rb +19 -0
- data/spec/models/timestamps_with_named_machine_example.rb +13 -0
- data/spec/models/valid_state_name.rb +23 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/spec_helpers/active_record.rb +8 -0
- data/spec/spec_helpers/dynamoid.rb +35 -0
- data/spec/spec_helpers/mongoid.rb +26 -0
- data/spec/spec_helpers/nobrainer.rb +15 -0
- data/spec/spec_helpers/redis.rb +18 -0
- data/spec/spec_helpers/remove_warnings.rb +1 -0
- data/spec/spec_helpers/sequel.rb +7 -0
- data/spec/unit/abstract_class_spec.rb +27 -0
- data/spec/unit/api_spec.rb +104 -0
- data/spec/unit/basic_two_state_machines_example_spec.rb +10 -0
- data/spec/unit/callback_multiple_spec.rb +304 -0
- data/spec/unit/callbacks_spec.rb +521 -0
- data/spec/unit/complex_example_spec.rb +93 -0
- data/spec/unit/complex_multiple_example_spec.rb +115 -0
- data/spec/unit/edge_cases_spec.rb +16 -0
- data/spec/unit/event_multiple_spec.rb +73 -0
- data/spec/unit/event_naming_spec.rb +16 -0
- data/spec/unit/event_spec.rb +394 -0
- data/spec/unit/exception_spec.rb +11 -0
- data/spec/unit/guard_arguments_check_spec.rb +9 -0
- data/spec/unit/guard_multiple_spec.rb +60 -0
- data/spec/unit/guard_spec.rb +89 -0
- data/spec/unit/guard_with_params_multiple_spec.rb +10 -0
- data/spec/unit/guard_with_params_spec.rb +14 -0
- data/spec/unit/guard_without_from_specified_spec.rb +10 -0
- data/spec/unit/initial_state_multiple_spec.rb +15 -0
- data/spec/unit/initial_state_spec.rb +12 -0
- data/spec/unit/inspection_multiple_spec.rb +205 -0
- data/spec/unit/inspection_spec.rb +153 -0
- data/spec/unit/invoker_spec.rb +189 -0
- data/spec/unit/invokers/base_invoker_spec.rb +72 -0
- data/spec/unit/invokers/class_invoker_spec.rb +95 -0
- data/spec/unit/invokers/literal_invoker_spec.rb +86 -0
- data/spec/unit/invokers/proc_invoker_spec.rb +86 -0
- data/spec/unit/localizer_spec.rb +109 -0
- data/spec/unit/memory_leak_spec.rb +38 -0
- data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
- data/spec/unit/namespaced_multiple_example_spec.rb +75 -0
- data/spec/unit/new_dsl_spec.rb +12 -0
- data/spec/unit/override_warning_spec.rb +94 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +635 -0
- data/spec/unit/persistence/active_record_persistence_spec.rb +852 -0
- data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +135 -0
- data/spec/unit/persistence/dynamoid_persistence_spec.rb +84 -0
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +200 -0
- data/spec/unit/persistence/mongoid_persistence_spec.rb +177 -0
- data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +198 -0
- data/spec/unit/persistence/no_brainer_persistence_spec.rb +158 -0
- data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
- data/spec/unit/persistence/redis_persistence_spec.rb +53 -0
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +148 -0
- data/spec/unit/persistence/sequel_persistence_spec.rb +368 -0
- data/spec/unit/readme_spec.rb +41 -0
- data/spec/unit/reloading_spec.rb +15 -0
- data/spec/unit/rspec_matcher_spec.rb +88 -0
- data/spec/unit/simple_custom_example_spec.rb +39 -0
- data/spec/unit/simple_example_spec.rb +57 -0
- data/spec/unit/simple_multiple_example_spec.rb +91 -0
- data/spec/unit/state_spec.rb +105 -0
- data/spec/unit/states_on_one_line_example_spec.rb +16 -0
- data/spec/unit/subclassing_multiple_spec.rb +74 -0
- data/spec/unit/subclassing_spec.rb +46 -0
- data/spec/unit/timestamps_spec.rb +32 -0
- data/spec/unit/transition_spec.rb +436 -0
- data/test/minitest_helper.rb +57 -0
- data/test/unit/minitest_matcher_test.rb +80 -0
- metadata +607 -60
- data/CHANGELOG +0 -33
- data/README.rdoc +0 -122
- data/TODO +0 -9
- data/doc/jamis.rb +0 -591
- data/lib/aasm/event.rb +0 -76
- data/lib/aasm/state.rb +0 -35
- data/lib/aasm/state_transition.rb +0 -36
data/lib/aasm/aasm.rb
CHANGED
|
@@ -1,185 +1,208 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'event')
|
|
2
|
-
require File.join(File.dirname(__FILE__), 'state')
|
|
3
|
-
require File.join(File.dirname(__FILE__), 'state_machine')
|
|
4
|
-
require File.join(File.dirname(__FILE__), 'persistence')
|
|
5
|
-
|
|
6
1
|
module AASM
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
class InvalidTransition < RuntimeError
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class UndefinedState < RuntimeError
|
|
15
|
-
end
|
|
2
|
+
# this is used internally as an argument default value to represent no value
|
|
3
|
+
NO_VALUE = :_aasm_no_value
|
|
16
4
|
|
|
5
|
+
# provide a state machine for the including class
|
|
6
|
+
# make sure to load class methods as well
|
|
7
|
+
# initialize persistence for the state machine
|
|
17
8
|
def self.included(base) #:nodoc:
|
|
18
9
|
base.extend AASM::ClassMethods
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
|
|
11
|
+
# do not overwrite existing state machines, which could have been created by
|
|
12
|
+
# inheritance, see class method inherited
|
|
13
|
+
AASM::StateMachineStore.register(base)
|
|
14
|
+
|
|
15
|
+
AASM::Persistence.load_persistence(base)
|
|
16
|
+
super
|
|
23
17
|
end
|
|
24
18
|
|
|
25
19
|
module ClassMethods
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
# make sure inheritance (aka subclassing) works with AASM
|
|
21
|
+
def inherited(base)
|
|
22
|
+
AASM::StateMachineStore.register(base, self)
|
|
23
|
+
|
|
28
24
|
super
|
|
29
25
|
end
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
# this is the entry point for all state and event definitions
|
|
28
|
+
def aasm(*args, &block)
|
|
29
|
+
if args[0].is_a?(Symbol) || args[0].is_a?(String)
|
|
30
|
+
# using custom name
|
|
31
|
+
state_machine_name = args[0].to_sym
|
|
32
|
+
options = args[1] || {}
|
|
34
33
|
else
|
|
35
|
-
|
|
34
|
+
# using the default state_machine_name
|
|
35
|
+
state_machine_name = :default
|
|
36
|
+
options = args[0] || {}
|
|
36
37
|
end
|
|
37
|
-
end
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
AASM::StateMachine[self].initial_state = state
|
|
41
|
-
end
|
|
39
|
+
AASM::StateMachineStore.fetch(self, true).register(state_machine_name, AASM::StateMachine.new(state_machine_name))
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
sm.initial_state = name unless sm.initial_state
|
|
41
|
+
# use a default despite the DSL configuration default.
|
|
42
|
+
# this is because configuration hasn't been setup for the AASM class but we are accessing a DSL option already for the class.
|
|
43
|
+
aasm_klass = options[:with_klass] || AASM::Base
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
aasm_current_state == name
|
|
50
|
-
end
|
|
51
|
-
end
|
|
45
|
+
raise ArgumentError, "The class #{aasm_klass} must inherit from AASM::Base!" unless aasm_klass.ancestors.include?(AASM::Base)
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
47
|
+
@aasm ||= Concurrent::Map.new
|
|
48
|
+
if @aasm[state_machine_name]
|
|
49
|
+
# make sure to use provided options
|
|
50
|
+
options.each do |key, value|
|
|
51
|
+
@aasm[state_machine_name].state_machine.config.send("#{key}=", value)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
# create a new base
|
|
55
|
+
@aasm[state_machine_name] = aasm_klass.new(
|
|
56
|
+
self,
|
|
57
|
+
state_machine_name,
|
|
58
|
+
AASM::StateMachineStore.fetch(self, true).machine(state_machine_name),
|
|
59
|
+
options
|
|
60
|
+
)
|
|
66
61
|
end
|
|
62
|
+
@aasm[state_machine_name].instance_eval(&block) if block # new DSL
|
|
63
|
+
@aasm[state_machine_name]
|
|
67
64
|
end
|
|
65
|
+
end # ClassMethods
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
# this is the entry point for all instance-level access to AASM
|
|
68
|
+
def aasm(name=:default)
|
|
69
|
+
unless AASM::StateMachineStore.fetch(self.class, true).machine(name)
|
|
70
|
+
raise AASM::UnknownStateMachineError.new("There is no state machine with the name '#{name}' defined in #{self.class.name}!")
|
|
71
71
|
end
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
AASM::StateMachine[self].events
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def aasm_states_for_select
|
|
78
|
-
AASM::StateMachine[self].states.map { |state| state.for_select }
|
|
79
|
-
end
|
|
80
|
-
|
|
72
|
+
@aasm ||= Concurrent::Map.new
|
|
73
|
+
@aasm[name.to_sym] ||= AASM::InstanceBase.new(self, name.to_sym)
|
|
81
74
|
end
|
|
82
75
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
def initialize_dup(other)
|
|
77
|
+
@aasm = Concurrent::Map.new
|
|
78
|
+
super
|
|
79
|
+
end
|
|
86
80
|
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Takes args and a from state and removes the first
|
|
84
|
+
# element from args if it is a valid to_state for
|
|
85
|
+
# the event given the from_state
|
|
86
|
+
def process_args(event, from_state, *args)
|
|
87
|
+
# If the first arg doesn't respond to to_sym then
|
|
88
|
+
# it isn't a symbol or string so it can't be a state
|
|
89
|
+
# name anyway
|
|
90
|
+
return args unless args.first.respond_to?(:to_sym)
|
|
91
|
+
if event.transitions_from_state(from_state).map(&:to).flatten.include?(args.first)
|
|
92
|
+
return args[1..-1]
|
|
89
93
|
end
|
|
90
|
-
return
|
|
91
|
-
aasm_determine_state_name(self.class.aasm_initial_state)
|
|
94
|
+
return args
|
|
92
95
|
end
|
|
93
96
|
|
|
94
|
-
def
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
def aasm_fire_event(state_machine_name, event_name, options, *args, &block)
|
|
98
|
+
event = self.class.aasm(state_machine_name).state_machine.events[event_name]
|
|
99
|
+
begin
|
|
100
|
+
old_state = aasm(state_machine_name).state_object_for_name(aasm(state_machine_name).current_state)
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
events = self.class.aasm_events.values.select {|event| event.transitions_from_state?(state) }
|
|
100
|
-
events.map {|event| event.name}
|
|
101
|
-
end
|
|
102
|
+
fire_default_callbacks(event, *process_args(event, aasm(state_machine_name).current_state, *args))
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
if may_fire_to = event.may_fire?(self, *args)
|
|
105
|
+
fire_exit_callbacks(old_state, *process_args(event, aasm(state_machine_name).current_state, *args))
|
|
106
|
+
if new_state_name = event.fire(self, {:may_fire => may_fire_to}, *args)
|
|
107
|
+
aasm_fired(state_machine_name, event, old_state, new_state_name, options, *args, &block)
|
|
108
|
+
else
|
|
109
|
+
aasm_failed(state_machine_name, event_name, old_state, event.failed_callbacks)
|
|
110
|
+
end
|
|
111
|
+
else
|
|
112
|
+
aasm_failed(state_machine_name, event_name, old_state, event.failed_callbacks)
|
|
113
|
+
end
|
|
114
|
+
rescue StandardError => e
|
|
115
|
+
event.fire_callbacks(:error, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) ||
|
|
116
|
+
event.fire_global_callbacks(:error_on_all_events, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) ||
|
|
117
|
+
raise(e)
|
|
118
|
+
false
|
|
119
|
+
ensure
|
|
120
|
+
event.fire_callbacks(:ensure, self, *process_args(event, aasm(state_machine_name).current_state, *args))
|
|
121
|
+
event.fire_global_callbacks(:ensure_on_all_events, self, *process_args(event, aasm(state_machine_name).current_state, *args))
|
|
108
122
|
end
|
|
109
|
-
self.aasm_current_state = state if save_success
|
|
110
|
-
|
|
111
|
-
save_success
|
|
112
123
|
end
|
|
113
124
|
|
|
114
|
-
def
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
def fire_default_callbacks(event, *processed_args)
|
|
126
|
+
event.fire_global_callbacks(
|
|
127
|
+
:before_all_events,
|
|
128
|
+
self,
|
|
129
|
+
*processed_args
|
|
130
|
+
)
|
|
120
131
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
else
|
|
128
|
-
raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc."
|
|
129
|
-
end
|
|
132
|
+
# new event before callback
|
|
133
|
+
event.fire_callbacks(
|
|
134
|
+
:before,
|
|
135
|
+
self,
|
|
136
|
+
*processed_args
|
|
137
|
+
)
|
|
130
138
|
end
|
|
131
139
|
|
|
132
|
-
def
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
obj
|
|
140
|
+
def fire_exit_callbacks(old_state, *processed_args)
|
|
141
|
+
old_state.fire_callbacks(:before_exit, self, *processed_args)
|
|
142
|
+
old_state.fire_callbacks(:exit, self, *processed_args)
|
|
136
143
|
end
|
|
137
144
|
|
|
138
|
-
def
|
|
139
|
-
|
|
140
|
-
event = self.class.aasm_events[name]
|
|
145
|
+
def aasm_fired(state_machine_name, event, old_state, new_state_name, options, *args)
|
|
146
|
+
persist = options[:persist]
|
|
141
147
|
|
|
142
|
-
|
|
148
|
+
new_state = aasm(state_machine_name).state_object_for_name(new_state_name)
|
|
149
|
+
callback_args = process_args(event, aasm(state_machine_name).current_state, *args)
|
|
143
150
|
|
|
144
|
-
|
|
145
|
-
event.call_action(:before, self)
|
|
146
|
-
|
|
147
|
-
new_state_name = event.fire(self, *args)
|
|
148
|
-
|
|
149
|
-
unless new_state_name.nil?
|
|
150
|
-
new_state = aasm_state_object_for_state(new_state_name)
|
|
151
|
-
|
|
152
|
-
# new before_ callbacks
|
|
153
|
-
old_state.call_action(:before_exit, self)
|
|
154
|
-
new_state.call_action(:before_enter, self)
|
|
155
|
-
|
|
156
|
-
new_state.call_action(:enter, self)
|
|
157
|
-
|
|
158
|
-
persist_successful = true
|
|
159
|
-
if persist
|
|
160
|
-
persist_successful = set_aasm_current_state_with_persistence(new_state_name)
|
|
161
|
-
event.execute_success_callback(self) if persist_successful
|
|
162
|
-
else
|
|
163
|
-
self.aasm_current_state = new_state_name
|
|
164
|
-
end
|
|
151
|
+
new_state.fire_callbacks(:before_enter, self, *callback_args)
|
|
165
152
|
|
|
166
|
-
|
|
167
|
-
old_state.call_action(:after_exit, self)
|
|
168
|
-
new_state.call_action(:after_enter, self)
|
|
169
|
-
event.call_action(:after, self)
|
|
153
|
+
new_state.fire_callbacks(:enter, self, *callback_args) # TODO: remove for AASM 4?
|
|
170
154
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
155
|
+
persist_successful = true
|
|
156
|
+
if persist
|
|
157
|
+
persist_successful = aasm(state_machine_name).set_current_state_with_persistence(new_state_name)
|
|
158
|
+
if persist_successful
|
|
159
|
+
yield if block_given?
|
|
160
|
+
event.fire_callbacks(:before_success, self, *callback_args)
|
|
161
|
+
event.fire_transition_callbacks(self, *process_args(event, old_state.name, *args))
|
|
162
|
+
event.fire_callbacks(:success, self, *callback_args)
|
|
174
163
|
end
|
|
164
|
+
else
|
|
165
|
+
aasm(state_machine_name).current_state = new_state_name
|
|
166
|
+
yield if block_given?
|
|
167
|
+
end
|
|
175
168
|
|
|
176
|
-
|
|
169
|
+
binding_event = event.options[:binding_event]
|
|
170
|
+
if binding_event
|
|
171
|
+
__send__("#{binding_event}#{'!' if persist}")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
if persist_successful
|
|
175
|
+
old_state.fire_callbacks(:after_exit, self, *callback_args)
|
|
176
|
+
new_state.fire_callbacks(:after_enter, self, *callback_args)
|
|
177
|
+
event.fire_callbacks(
|
|
178
|
+
:after,
|
|
179
|
+
self,
|
|
180
|
+
*process_args(event, old_state.name, *args)
|
|
181
|
+
)
|
|
182
|
+
event.fire_global_callbacks(
|
|
183
|
+
:after_all_events,
|
|
184
|
+
self,
|
|
185
|
+
*process_args(event, old_state.name, *args)
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
self.aasm_event_fired(event.name, old_state.name, aasm(state_machine_name).current_state) if self.respond_to?(:aasm_event_fired)
|
|
177
189
|
else
|
|
178
|
-
if self.respond_to?(:aasm_event_failed)
|
|
179
|
-
|
|
180
|
-
end
|
|
190
|
+
self.aasm_event_failed(event.name, old_state.name) if self.respond_to?(:aasm_event_failed)
|
|
191
|
+
end
|
|
181
192
|
|
|
193
|
+
persist_successful
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def aasm_failed(state_machine_name, event_name, old_state, failures = [])
|
|
197
|
+
if self.respond_to?(:aasm_event_failed)
|
|
198
|
+
self.aasm_event_failed(event_name, old_state.name)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
if AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_transitions
|
|
202
|
+
raise AASM::InvalidTransition.new(self, event_name, state_machine_name, failures)
|
|
203
|
+
else
|
|
182
204
|
false
|
|
183
205
|
end
|
|
184
206
|
end
|
|
207
|
+
|
|
185
208
|
end
|
data/lib/aasm/base.rb
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module AASM
|
|
4
|
+
class Base
|
|
5
|
+
|
|
6
|
+
attr_reader :klass, :state_machine
|
|
7
|
+
|
|
8
|
+
def initialize(klass, name, state_machine, options={}, &block)
|
|
9
|
+
@klass = klass
|
|
10
|
+
@name = name
|
|
11
|
+
# @state_machine = klass.aasm(@name).state_machine
|
|
12
|
+
@state_machine = state_machine
|
|
13
|
+
@state_machine.config.column ||= (options[:column] || default_column).to_sym
|
|
14
|
+
# @state_machine.config.column = options[:column].to_sym if options[:column] # master
|
|
15
|
+
@options = options
|
|
16
|
+
|
|
17
|
+
# let's cry if the transition is invalid
|
|
18
|
+
configure :whiny_transitions, true
|
|
19
|
+
|
|
20
|
+
# create named scopes for each state
|
|
21
|
+
configure :create_scopes, true
|
|
22
|
+
|
|
23
|
+
# don't store any new state if the model is invalid (in ActiveRecord)
|
|
24
|
+
configure :skip_validation_on_save, false
|
|
25
|
+
|
|
26
|
+
# raise if the model is invalid (in ActiveRecord)
|
|
27
|
+
configure :whiny_persistence, false
|
|
28
|
+
|
|
29
|
+
# Use transactions (in ActiveRecord)
|
|
30
|
+
configure :use_transactions, true
|
|
31
|
+
|
|
32
|
+
# use requires_new for nested transactions (in ActiveRecord)
|
|
33
|
+
configure :requires_new_transaction, true
|
|
34
|
+
|
|
35
|
+
# use pessimistic locking (in ActiveRecord)
|
|
36
|
+
# true for FOR UPDATE lock
|
|
37
|
+
# string for a specific lock type i.e. FOR UPDATE NOWAIT
|
|
38
|
+
configure :requires_lock, false
|
|
39
|
+
|
|
40
|
+
# automatically set `"#{state_name}_at" = ::Time.now` on state changes
|
|
41
|
+
configure :timestamps, false
|
|
42
|
+
|
|
43
|
+
# set to true to forbid direct assignment of aasm_state column (in ActiveRecord)
|
|
44
|
+
configure :no_direct_assignment, false
|
|
45
|
+
|
|
46
|
+
# allow a AASM::Base sub-class to be used for state machine
|
|
47
|
+
configure :with_klass, AASM::Base
|
|
48
|
+
|
|
49
|
+
configure :enum, nil
|
|
50
|
+
|
|
51
|
+
# Set to true to namespace reader methods and constants
|
|
52
|
+
configure :namespace, false
|
|
53
|
+
|
|
54
|
+
# Configure a logger, with default being a Logger to STDERR
|
|
55
|
+
configure :logger, Logger.new(STDERR)
|
|
56
|
+
|
|
57
|
+
# setup timestamp-setting callback if enabled
|
|
58
|
+
setup_timestamps(@name)
|
|
59
|
+
|
|
60
|
+
# make sure to raise an error if no_direct_assignment is enabled
|
|
61
|
+
# and attribute is directly assigned though
|
|
62
|
+
setup_no_direct_assignment(@name)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# This method is both a getter and a setter
|
|
66
|
+
def attribute_name(column_name=nil)
|
|
67
|
+
if column_name
|
|
68
|
+
@state_machine.config.column = column_name.to_sym
|
|
69
|
+
else
|
|
70
|
+
@state_machine.config.column ||= :aasm_state
|
|
71
|
+
end
|
|
72
|
+
@state_machine.config.column
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def initial_state(new_initial_state=nil)
|
|
76
|
+
if new_initial_state
|
|
77
|
+
@state_machine.initial_state = new_initial_state
|
|
78
|
+
else
|
|
79
|
+
@state_machine.initial_state
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# define a state
|
|
84
|
+
# args
|
|
85
|
+
# [0] state
|
|
86
|
+
# [1] options (or nil)
|
|
87
|
+
# or
|
|
88
|
+
# [0] state
|
|
89
|
+
# [1..] state
|
|
90
|
+
def state(*args)
|
|
91
|
+
names, options = interpret_state_args(args)
|
|
92
|
+
names.each do |name|
|
|
93
|
+
@state_machine.add_state(name, klass, options)
|
|
94
|
+
|
|
95
|
+
aasm_name = @name.to_sym
|
|
96
|
+
state = name.to_sym
|
|
97
|
+
|
|
98
|
+
method_name = namespace? ? "#{namespace}_#{name}" : name
|
|
99
|
+
safely_define_method klass, "#{method_name}?", -> do
|
|
100
|
+
aasm(aasm_name).current_state == state
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
const_name = namespace? ? "STATE_#{namespace.upcase}_#{name.upcase}" : "STATE_#{name.upcase}"
|
|
104
|
+
unless klass.const_defined?(const_name)
|
|
105
|
+
klass.const_set(const_name, name)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# define an event
|
|
111
|
+
def event(name, options={}, &block)
|
|
112
|
+
@state_machine.add_event(name, options, &block)
|
|
113
|
+
|
|
114
|
+
aasm_name = @name.to_sym
|
|
115
|
+
event = name.to_sym
|
|
116
|
+
|
|
117
|
+
# an addition over standard aasm so that, before firing an event, you can ask
|
|
118
|
+
# may_event? and get back a boolean that tells you whether the guard method
|
|
119
|
+
# on the transition will let this happen.
|
|
120
|
+
safely_define_method klass, "may_#{name}?", ->(*args) do
|
|
121
|
+
aasm(aasm_name).may_fire_event?(event, *args)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
safely_define_method klass, "#{name}!", ->(*args, &block) do
|
|
125
|
+
aasm(aasm_name).current_event = :"#{name}!"
|
|
126
|
+
aasm_fire_event(aasm_name, event, {:persist => true}, *args, &block)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
safely_define_method klass, name, ->(*args, &block) do
|
|
130
|
+
aasm(aasm_name).current_event = event
|
|
131
|
+
aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
skip_instance_level_validation(event, name, aasm_name, klass)
|
|
135
|
+
|
|
136
|
+
# Create aliases for the event methods. Keep the old names to maintain backwards compatibility.
|
|
137
|
+
if namespace?
|
|
138
|
+
klass.send(:alias_method, "may_#{name}_#{namespace}?", "may_#{name}?")
|
|
139
|
+
klass.send(:alias_method, "#{name}_#{namespace}!", "#{name}!")
|
|
140
|
+
klass.send(:alias_method, "#{name}_#{namespace}", name)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def after_all_transitions(*callbacks, &block)
|
|
146
|
+
@state_machine.add_global_callbacks(:after_all_transitions, *callbacks, &block)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def after_all_transactions(*callbacks, &block)
|
|
150
|
+
@state_machine.add_global_callbacks(:after_all_transactions, *callbacks, &block)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def before_all_transactions(*callbacks, &block)
|
|
154
|
+
@state_machine.add_global_callbacks(:before_all_transactions, *callbacks, &block)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def before_all_events(*callbacks, &block)
|
|
158
|
+
@state_machine.add_global_callbacks(:before_all_events, *callbacks, &block)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def after_all_events(*callbacks, &block)
|
|
162
|
+
@state_machine.add_global_callbacks(:after_all_events, *callbacks, &block)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def error_on_all_events(*callbacks, &block)
|
|
166
|
+
@state_machine.add_global_callbacks(:error_on_all_events, *callbacks, &block)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def ensure_on_all_events(*callbacks, &block)
|
|
170
|
+
@state_machine.add_global_callbacks(:ensure_on_all_events, *callbacks, &block)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def states
|
|
174
|
+
@state_machine.states
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def events
|
|
178
|
+
@state_machine.events.values
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# aasm.event(:event_name).human?
|
|
182
|
+
def human_event_name(event) # event_name?
|
|
183
|
+
AASM::Localizer.new.human_event_name(klass, event)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def states_for_select
|
|
187
|
+
states.map { |state| state.for_select }
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def from_states_for_state(state, options={})
|
|
191
|
+
if options[:transition]
|
|
192
|
+
@state_machine.events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten
|
|
193
|
+
else
|
|
194
|
+
|
|
195
|
+
events.map {|e| e.transitions_to_state(state)}.flatten.map(&:from).flatten
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
private
|
|
200
|
+
|
|
201
|
+
def default_column
|
|
202
|
+
@name.to_sym == :default ? :aasm_state : @name.to_sym
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def configure(key, default_value)
|
|
206
|
+
if @options.key?(key)
|
|
207
|
+
@state_machine.config.send("#{key}=", @options[key])
|
|
208
|
+
elsif @state_machine.config.send(key).nil?
|
|
209
|
+
@state_machine.config.send("#{key}=", default_value)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def safely_define_method(klass, method_name, method_definition)
|
|
214
|
+
# Warn if method exists and it did not originate from an enum
|
|
215
|
+
if klass.method_defined?(method_name) &&
|
|
216
|
+
! ( @state_machine.config.enum &&
|
|
217
|
+
klass.respond_to?(:defined_enums) &&
|
|
218
|
+
klass.defined_enums.values.any?{ |methods|
|
|
219
|
+
methods.keys{| enum | enum + '?' == method_name }
|
|
220
|
+
})
|
|
221
|
+
unless AASM::Configuration.hide_warnings
|
|
222
|
+
@state_machine.config.logger.warn "#{klass.name}: overriding method '#{method_name}'!"
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
klass.send(:define_method, method_name, method_definition)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def namespace?
|
|
230
|
+
!!@state_machine.config.namespace
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def namespace
|
|
234
|
+
if @state_machine.config.namespace == true
|
|
235
|
+
@name
|
|
236
|
+
else
|
|
237
|
+
@state_machine.config.namespace
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def interpret_state_args(args)
|
|
242
|
+
if args.last.is_a?(Hash) && args.size == 2
|
|
243
|
+
[[args.first], args.last]
|
|
244
|
+
elsif args.size > 0
|
|
245
|
+
[args, {}]
|
|
246
|
+
else
|
|
247
|
+
raise "count not parse states: #{args}"
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def skip_instance_level_validation(event, name, aasm_name, klass)
|
|
252
|
+
# Overrides the skip_validation config for an instance (If skip validation is set to false in original config) and
|
|
253
|
+
# restores it back to the original value after the event is fired.
|
|
254
|
+
safely_define_method klass, "#{name}_without_validation!", ->(*args, &block) do
|
|
255
|
+
original_config = AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save
|
|
256
|
+
begin
|
|
257
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save = true unless original_config
|
|
258
|
+
aasm(aasm_name).current_event = :"#{name}!"
|
|
259
|
+
aasm_fire_event(aasm_name, event, {:persist => true}, *args, &block)
|
|
260
|
+
ensure
|
|
261
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save = original_config
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def setup_timestamps(aasm_name)
|
|
267
|
+
return unless @state_machine.config.timestamps
|
|
268
|
+
|
|
269
|
+
after_all_transitions do
|
|
270
|
+
if self.class.aasm(:"#{aasm_name}").state_machine.config.timestamps
|
|
271
|
+
ts_setter = "#{aasm(aasm_name).to_state}_at="
|
|
272
|
+
respond_to?(ts_setter) && send(ts_setter, ::Time.now)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def setup_no_direct_assignment(aasm_name)
|
|
278
|
+
return unless @state_machine.config.no_direct_assignment
|
|
279
|
+
|
|
280
|
+
@klass.send(:define_method, "#{@state_machine.config.column}=") do |state_name|
|
|
281
|
+
if self.class.aasm(:"#{aasm_name}").state_machine.config.no_direct_assignment
|
|
282
|
+
raise AASM::NoDirectAssignmentError.new('direct assignment of AASM column has been disabled (see AASM configuration for this class)')
|
|
283
|
+
else
|
|
284
|
+
super(state_name)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
end
|
|
290
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module AASM
|
|
2
|
+
class Configuration
|
|
3
|
+
# for all persistence layers: which database column to use?
|
|
4
|
+
attr_accessor :column
|
|
5
|
+
|
|
6
|
+
# let's cry if the transition is invalid
|
|
7
|
+
attr_accessor :whiny_transitions
|
|
8
|
+
|
|
9
|
+
# for all persistence layers: create named scopes for each state
|
|
10
|
+
attr_accessor :create_scopes
|
|
11
|
+
|
|
12
|
+
# for ActiveRecord: when the model is invalid, true -> raise, false -> return false
|
|
13
|
+
attr_accessor :whiny_persistence
|
|
14
|
+
|
|
15
|
+
# for ActiveRecord: store the new state even if the model is invalid and return true
|
|
16
|
+
attr_accessor :skip_validation_on_save
|
|
17
|
+
|
|
18
|
+
# for ActiveRecord: use transactions
|
|
19
|
+
attr_accessor :use_transactions
|
|
20
|
+
|
|
21
|
+
# for ActiveRecord: use requires_new for nested transactions?
|
|
22
|
+
attr_accessor :requires_new_transaction
|
|
23
|
+
|
|
24
|
+
# for ActiveRecord: use pessimistic locking
|
|
25
|
+
attr_accessor :requires_lock
|
|
26
|
+
|
|
27
|
+
# automatically set `"#{state_name}_at" = ::Time.now` on state changes
|
|
28
|
+
attr_accessor :timestamps
|
|
29
|
+
|
|
30
|
+
# forbid direct assignment in aasm_state column (in ActiveRecord)
|
|
31
|
+
attr_accessor :no_direct_assignment
|
|
32
|
+
|
|
33
|
+
# allow a AASM::Base sub-class to be used for state machine
|
|
34
|
+
attr_accessor :with_klass
|
|
35
|
+
|
|
36
|
+
attr_accessor :enum
|
|
37
|
+
|
|
38
|
+
# namespace reader methods and constants
|
|
39
|
+
attr_accessor :namespace
|
|
40
|
+
|
|
41
|
+
# Configure a logger, with default being a Logger to STDERR
|
|
42
|
+
attr_accessor :logger
|
|
43
|
+
|
|
44
|
+
class << self
|
|
45
|
+
attr_accessor :hide_warnings
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|