aasm 4.11.1 → 4.12.1
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 +4 -4
- data/.travis.yml +19 -16
- data/Appraisals +46 -0
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTING.md +24 -0
- data/Gemfile +4 -21
- data/README.md +154 -39
- data/Rakefile +6 -1
- data/TESTING.md +25 -0
- data/aasm.gemspec +3 -0
- data/gemfiles/rails_3.2.gemfile +13 -0
- data/gemfiles/rails_4.0.gemfile +8 -9
- data/gemfiles/rails_4.2.gemfile +10 -9
- data/gemfiles/rails_4.2_mongoid_5.gemfile +5 -9
- data/gemfiles/rails_5.0.gemfile +8 -16
- data/lib/aasm/aasm.rb +9 -3
- data/lib/aasm/base.rb +11 -1
- data/lib/aasm/configuration.rb +4 -0
- data/lib/aasm/core/event.rb +18 -4
- data/lib/aasm/core/state.rb +7 -0
- data/lib/aasm/core/transition.rb +10 -1
- data/lib/aasm/instance_base.rb +0 -2
- 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 +25 -101
- data/lib/aasm/persistence/base.rb +7 -3
- data/lib/aasm/persistence/mongoid_persistence.rb +25 -31
- data/lib/aasm/persistence/orm.rb +142 -0
- data/lib/aasm/persistence/redis_persistence.rb +16 -11
- data/lib/aasm/persistence/sequel_persistence.rb +36 -63
- data/lib/aasm/persistence.rb +0 -3
- data/lib/aasm/state_machine.rb +4 -2
- data/lib/aasm/state_machine_store.rb +5 -2
- data/lib/aasm/version.rb +1 -1
- data/lib/generators/active_record/templates/migration.rb +1 -1
- data/lib/generators/active_record/templates/migration_existing.rb +1 -1
- data/lib/motion-aasm.rb +2 -1
- data/spec/generators/active_record_generator_spec.rb +42 -39
- data/spec/generators/mongoid_generator_spec.rb +4 -6
- data/spec/models/active_record/complex_active_record_example.rb +5 -1
- data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
- data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
- data/spec/models/{transactor.rb → active_record/transactor.rb} +0 -2
- data/spec/models/{validator.rb → active_record/validator.rb} +0 -2
- data/spec/models/callbacks/basic.rb +5 -2
- data/spec/models/guard_with_params.rb +1 -1
- data/spec/models/guardian_without_from_specified.rb +18 -0
- data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/validator_mongoid.rb +100 -0
- data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
- data/spec/models/namespaced_multiple_example.rb +14 -0
- data/spec/models/parametrised_event.rb +7 -0
- data/spec/models/{mongo_mapper/complex_mongo_mapper_example.rb → redis/complex_redis_example.rb} +8 -5
- 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 +4 -3
- data/spec/models/sequel/invalid_persistor.rb +52 -0
- data/spec/models/sequel/sequel_multiple.rb +13 -13
- data/spec/models/sequel/sequel_simple.rb +13 -12
- 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/simple_multiple_example.rb +12 -0
- data/spec/models/sub_class.rb +34 -0
- data/spec/spec_helper.rb +0 -33
- data/spec/spec_helpers/active_record.rb +7 -0
- data/spec/spec_helpers/dynamoid.rb +33 -0
- data/spec/spec_helpers/mongoid.rb +7 -0
- data/spec/spec_helpers/redis.rb +15 -0
- data/spec/spec_helpers/remove_warnings.rb +1 -0
- data/spec/spec_helpers/sequel.rb +7 -0
- data/spec/unit/api_spec.rb +76 -73
- data/spec/unit/callbacks_spec.rb +5 -0
- data/spec/unit/event_spec.rb +12 -0
- data/spec/unit/guard_spec.rb +17 -0
- data/spec/unit/guard_with_params_spec.rb +4 -0
- data/spec/unit/guard_without_from_specified_spec.rb +10 -0
- data/spec/unit/localizer_spec.rb +55 -53
- data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
- data/spec/unit/namespaced_multiple_example_spec.rb +22 -0
- data/spec/unit/override_warning_spec.rb +8 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +453 -449
- data/spec/unit/persistence/active_record_persistence_spec.rb +524 -502
- data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
- data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +83 -9
- data/spec/unit/persistence/mongoid_persistence_spec.rb +85 -9
- data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
- data/spec/unit/persistence/redis_persistence_spec.rb +8 -32
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +6 -11
- data/spec/unit/persistence/sequel_persistence_spec.rb +278 -10
- data/spec/unit/simple_multiple_example_spec.rb +28 -0
- data/spec/unit/subclassing_multiple_spec.rb +37 -2
- data/spec/unit/subclassing_spec.rb +17 -2
- data/test/minitest_helper.rb +57 -0
- data/test/unit/minitest_matcher_test.rb +80 -0
- metadata +99 -28
- data/gemfiles/rails_3.2_stable.gemfile +0 -15
- data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -16
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -17
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
- data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -149
- data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -96
- /data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module AASM
|
|
2
|
+
module Persistence
|
|
3
|
+
# This module adds transactional support for any database that supports it.
|
|
4
|
+
# This includes rollback capability and rollback/commit callbacks.
|
|
5
|
+
module ORM
|
|
6
|
+
|
|
7
|
+
# Writes <tt>state</tt> to the state column and persists it to the database
|
|
8
|
+
#
|
|
9
|
+
# foo = Foo.find(1)
|
|
10
|
+
# foo.aasm.current_state # => :opened
|
|
11
|
+
# foo.close!
|
|
12
|
+
# foo.aasm.current_state # => :closed
|
|
13
|
+
# Foo.find(1).aasm.current_state # => :closed
|
|
14
|
+
#
|
|
15
|
+
# NOTE: intended to be called from an event
|
|
16
|
+
def aasm_write_state(state, name=:default)
|
|
17
|
+
attribute_name = self.class.aasm(name).attribute_name
|
|
18
|
+
old_value = aasm_read_attribute(attribute_name)
|
|
19
|
+
aasm_write_state_attribute state, name
|
|
20
|
+
|
|
21
|
+
success = if aasm_skipping_validations(name)
|
|
22
|
+
aasm_update_column(attribute_name, aasm_raw_attribute_value(state, name))
|
|
23
|
+
else
|
|
24
|
+
aasm_save
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
unless success
|
|
28
|
+
aasm_rollback(name, old_value)
|
|
29
|
+
aasm_raise_invalid_record if aasm_whiny_persistence(name)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
success
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Writes <tt>state</tt> to the state field, but does not persist it to the database
|
|
36
|
+
#
|
|
37
|
+
# foo = Foo.find(1)
|
|
38
|
+
# foo.aasm.current_state # => :opened
|
|
39
|
+
# foo.close
|
|
40
|
+
# foo.aasm.current_state # => :closed
|
|
41
|
+
# Foo.find(1).aasm.current_state # => :opened
|
|
42
|
+
# foo.save
|
|
43
|
+
# foo.aasm.current_state # => :closed
|
|
44
|
+
# Foo.find(1).aasm.current_state # => :closed
|
|
45
|
+
#
|
|
46
|
+
# NOTE: intended to be called from an event
|
|
47
|
+
def aasm_write_state_without_persistence(state, name=:default)
|
|
48
|
+
aasm_write_state_attribute(state, name)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
# Save the record and return true if it succeeded/false otherwise.
|
|
54
|
+
def aasm_save
|
|
55
|
+
raise("Define #aasm_save_without_error in the AASM Persistence class.")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def aasm_raise_invalid_record
|
|
59
|
+
raise("Define #aasm_raise_invalid_record in the AASM Persistence class.")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Update only the column without running validations.
|
|
63
|
+
def aasm_update_column(attribute_name, value)
|
|
64
|
+
raise("Define #aasm_update_column in the AASM Persistence class.")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def aasm_read_attribute(name)
|
|
68
|
+
raise("Define #aasm_read_attribute the AASM Persistence class.")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def aasm_write_attribute(name, value)
|
|
72
|
+
raise("Define #aasm_write_attribute in the AASM Persistence class.")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns true or false if transaction completed successfully.
|
|
76
|
+
def aasm_transaction(requires_new, requires_lock)
|
|
77
|
+
raise("Define #aasm_transaction the AASM Persistence class.")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def aasm_supports_transactions?
|
|
81
|
+
true
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def aasm_write_state_attribute(state, name=:default)
|
|
85
|
+
aasm_write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def aasm_raw_attribute_value(state, _name=:default)
|
|
89
|
+
state.to_s
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def aasm_rollback(name, old_value)
|
|
93
|
+
aasm_write_attribute(self.class.aasm(name).attribute_name, old_value)
|
|
94
|
+
false
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def aasm_whiny_persistence(state_machine_name)
|
|
98
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def aasm_skipping_validations(state_machine_name)
|
|
102
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def requires_new?(state_machine_name)
|
|
106
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_new_transaction
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def requires_lock?(state_machine_name)
|
|
110
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_lock
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Returns true if event was fired successfully and transaction completed.
|
|
114
|
+
def aasm_fire_event(state_machine_name, name, options, *args, &block)
|
|
115
|
+
if aasm_supports_transactions? && options[:persist]
|
|
116
|
+
event = self.class.aasm(state_machine_name).state_machine.events[name]
|
|
117
|
+
event.fire_callbacks(:before_transaction, self, *args)
|
|
118
|
+
event.fire_global_callbacks(:before_all_transactions, self, *args)
|
|
119
|
+
|
|
120
|
+
begin
|
|
121
|
+
success = aasm_transaction(requires_new?(state_machine_name), requires_lock?(state_machine_name)) do
|
|
122
|
+
super
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if success
|
|
126
|
+
event.fire_callbacks(:after_commit, self, *args)
|
|
127
|
+
event.fire_global_callbacks(:after_all_commits, self, *args)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
success
|
|
131
|
+
ensure
|
|
132
|
+
event.fire_callbacks(:after_transaction, self, *args)
|
|
133
|
+
event.fire_global_callbacks(:after_all_transactions, self, *args)
|
|
134
|
+
end
|
|
135
|
+
else
|
|
136
|
+
super
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end # Transactional
|
|
141
|
+
end # Persistence
|
|
142
|
+
end # AASM
|
|
@@ -8,13 +8,12 @@ module AASM
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
module InstanceMethods
|
|
11
|
-
#
|
|
11
|
+
# Initialize with default values
|
|
12
12
|
#
|
|
13
|
-
#
|
|
13
|
+
# Redis::Objects removes the key from Redis when set to `nil`
|
|
14
14
|
def initialize(*args)
|
|
15
15
|
super
|
|
16
|
-
|
|
17
|
-
state.value = aasm.determine_state_name(self.class.aasm.initial_state)
|
|
16
|
+
aasm_ensure_initial_state
|
|
18
17
|
end
|
|
19
18
|
# Returns the value of the aasm.attribute_name - called from <tt>aasm.current_state</tt>
|
|
20
19
|
#
|
|
@@ -68,8 +67,10 @@ module AASM
|
|
|
68
67
|
# foo.aasm_state # => nil
|
|
69
68
|
#
|
|
70
69
|
def aasm_ensure_initial_state
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |name|
|
|
71
|
+
aasm_column = self.class.aasm(name).attribute_name
|
|
72
|
+
aasm(name).enter_initial_state if send(aasm_column).value.blank?
|
|
73
|
+
end
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
# Writes <tt>state</tt> to the state column and persists it to the database
|
|
@@ -81,12 +82,16 @@ module AASM
|
|
|
81
82
|
# Foo[1].aasm.current_state # => :closed
|
|
82
83
|
#
|
|
83
84
|
# NOTE: intended to be called from an event
|
|
84
|
-
def aasm_write_state(state)
|
|
85
|
-
aasm_column = self.class.aasm.attribute_name
|
|
86
|
-
|
|
85
|
+
def aasm_write_state(state, name=:default)
|
|
86
|
+
aasm_column = self.class.aasm(name).attribute_name
|
|
87
|
+
send("#{aasm_column}").value = state
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
|
91
|
+
# (but actually it still does)
|
|
92
|
+
#
|
|
93
|
+
# With Redis::Objects it's not possible to skip persisting - it's not an ORM,
|
|
94
|
+
# it does not operate like an AR model and does not know how to postpone changes.
|
|
90
95
|
#
|
|
91
96
|
# foo = Foo[1]
|
|
92
97
|
# foo.aasm.current_state # => :opened
|
|
@@ -98,8 +103,8 @@ module AASM
|
|
|
98
103
|
# Foo[1].aasm.current_state # => :closed
|
|
99
104
|
#
|
|
100
105
|
# NOTE: intended to be called from an event
|
|
101
|
-
def aasm_write_state_without_persistence(state)
|
|
102
|
-
|
|
106
|
+
def aasm_write_state_without_persistence(state, name=:default)
|
|
107
|
+
aasm_write_state(state, name)
|
|
103
108
|
end
|
|
104
109
|
end
|
|
105
110
|
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
require 'aasm/persistence/orm'
|
|
1
2
|
module AASM
|
|
2
3
|
module Persistence
|
|
3
4
|
module SequelPersistence
|
|
4
5
|
def self.included(base)
|
|
5
6
|
base.send(:include, AASM::Persistence::Base)
|
|
7
|
+
base.send(:include, AASM::Persistence::ORM)
|
|
6
8
|
base.send(:include, AASM::Persistence::SequelPersistence::InstanceMethods)
|
|
7
9
|
end
|
|
8
10
|
|
|
@@ -17,42 +19,42 @@ module AASM
|
|
|
17
19
|
super
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
elsif state.nil?
|
|
50
|
-
nil
|
|
51
|
-
else
|
|
52
|
-
state.to_sym
|
|
22
|
+
def aasm_raise_invalid_record
|
|
23
|
+
raise Sequel::ValidationFailed.new(self)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def aasm_new_record?
|
|
27
|
+
new?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns nil if fails silently
|
|
31
|
+
# http://sequel.jeremyevans.net/rdoc/classes/Sequel/Model/InstanceMethods.html#method-i-save
|
|
32
|
+
def aasm_save
|
|
33
|
+
!save(raise_on_failure: false).nil?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def aasm_read_attribute(name)
|
|
37
|
+
send(name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def aasm_write_attribute(name, value)
|
|
41
|
+
send("#{name}=", value)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def aasm_transaction(requires_new, requires_lock)
|
|
45
|
+
self.class.db.transaction(savepoint: requires_new) do
|
|
46
|
+
if requires_lock
|
|
47
|
+
# http://sequel.jeremyevans.net/rdoc/classes/Sequel/Model/InstanceMethods.html#method-i-lock-21
|
|
48
|
+
requires_lock.is_a?(String) ? lock!(requires_lock) : lock!
|
|
49
|
+
end
|
|
50
|
+
yield
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
|
|
54
|
+
def aasm_update_column(attribute_name, value)
|
|
55
|
+
this.update(attribute_name => value)
|
|
56
|
+
end
|
|
57
|
+
|
|
56
58
|
# Ensures that if the aasm_state column is nil and the record is new
|
|
57
59
|
# that the initial state gets populated before validation on create
|
|
58
60
|
#
|
|
@@ -72,39 +74,10 @@ module AASM
|
|
|
72
74
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
|
|
73
75
|
aasm(state_machine_name).enter_initial_state if
|
|
74
76
|
(new? || values.key?(self.class.aasm(state_machine_name).attribute_name)) &&
|
|
75
|
-
|
|
77
|
+
send(self.class.aasm(state_machine_name).attribute_name).to_s.strip.empty?
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
|
|
79
|
-
# Writes <tt>state</tt> to the state column and persists it to the database
|
|
80
|
-
#
|
|
81
|
-
# foo = Foo[1]
|
|
82
|
-
# foo.aasm.current_state # => :opened
|
|
83
|
-
# foo.close!
|
|
84
|
-
# foo.aasm.current_state # => :closed
|
|
85
|
-
# Foo[1].aasm.current_state # => :closed
|
|
86
|
-
#
|
|
87
|
-
# NOTE: intended to be called from an event
|
|
88
|
-
def aasm_write_state state, name=:default
|
|
89
|
-
aasm_column = self.class.aasm(name).attribute_name
|
|
90
|
-
update_only({aasm_column => state.to_s}, aasm_column)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
|
94
|
-
#
|
|
95
|
-
# foo = Foo[1]
|
|
96
|
-
# foo.aasm.current_state # => :opened
|
|
97
|
-
# foo.close
|
|
98
|
-
# foo.aasm.current_state # => :closed
|
|
99
|
-
# Foo[1].aasm.current_state # => :opened
|
|
100
|
-
# foo.save
|
|
101
|
-
# foo.aasm.current_state # => :closed
|
|
102
|
-
# Foo[1].aasm.current_state # => :closed
|
|
103
|
-
#
|
|
104
|
-
# NOTE: intended to be called from an event
|
|
105
|
-
def aasm_write_state_without_persistence state, name=:default
|
|
106
|
-
send("#{self.class.aasm(name).attribute_name}=", state.to_s)
|
|
107
|
-
end
|
|
108
81
|
end
|
|
109
82
|
end
|
|
110
83
|
end
|
data/lib/aasm/persistence.rb
CHANGED
|
@@ -12,9 +12,6 @@ module AASM
|
|
|
12
12
|
elsif hierarchy.include?("Mongoid::Document")
|
|
13
13
|
require_persistence :mongoid
|
|
14
14
|
include_persistence base, :mongoid
|
|
15
|
-
elsif hierarchy.include?("MongoMapper::Document")
|
|
16
|
-
require_persistence :mongo_mapper
|
|
17
|
-
include_persistence base, :mongo_mapper
|
|
18
15
|
elsif hierarchy.include?("Sequel::Model")
|
|
19
16
|
require_persistence :sequel
|
|
20
17
|
include_persistence base, :sequel
|
data/lib/aasm/state_machine.rb
CHANGED
|
@@ -16,8 +16,10 @@ module AASM
|
|
|
16
16
|
# called internally by Ruby 1.9 after clone()
|
|
17
17
|
def initialize_copy(orig)
|
|
18
18
|
super
|
|
19
|
-
@states =
|
|
20
|
-
@events =
|
|
19
|
+
@states = orig.states.collect { |state| state.clone }
|
|
20
|
+
@events = {}
|
|
21
|
+
orig.events.each_pair { |name, event| @events[name] = event.clone }
|
|
22
|
+
@global_callbacks = @global_callbacks.dup
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def add_state(state_name, klass, options)
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
require 'concurrent'
|
|
1
2
|
module AASM
|
|
2
3
|
class StateMachineStore
|
|
4
|
+
@stores = Concurrent::Map.new
|
|
5
|
+
|
|
3
6
|
class << self
|
|
4
7
|
def stores
|
|
5
|
-
@stores
|
|
8
|
+
@stores
|
|
6
9
|
end
|
|
7
10
|
|
|
8
11
|
# do not overwrite existing state machines, which could have been created by
|
|
@@ -38,7 +41,7 @@ module AASM
|
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def initialize
|
|
41
|
-
@machines =
|
|
44
|
+
@machines = Concurrent::Map.new
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
def clone
|
data/lib/aasm/version.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Add<%= column_name.camelize %>To<%= table_name.camelize %> < ActiveRecord::Migration
|
|
1
|
+
class Add<%= column_name.camelize %>To<%= table_name.camelize %> < ActiveRecord::Migration[<%= ActiveRecord::VERSION::STRING.to_f %>]
|
|
2
2
|
def change
|
|
3
3
|
add_column :<%= table_name %>, :<%= column_name %>, :string
|
|
4
4
|
end
|
data/lib/motion-aasm.rb
CHANGED
|
@@ -11,9 +11,10 @@ file_dependencies = {
|
|
|
11
11
|
|
|
12
12
|
exclude_files = [
|
|
13
13
|
'aasm/rspec.*',
|
|
14
|
+
'aasm/minitest.*',
|
|
15
|
+
'aasm/minitest_spec.*',
|
|
14
16
|
'aasm/persistence/active_record_persistence.rb',
|
|
15
17
|
'aasm/persistence/dynamoid_persistence.rb',
|
|
16
|
-
'aasm/persistence/mongo_mapper_persistence.rb',
|
|
17
18
|
'aasm/persistence/mongoid_persistence.rb',
|
|
18
19
|
'aasm/persistence/sequel_persistence.rb',
|
|
19
20
|
'aasm/persistence/redis_persistence.rb'
|
|
@@ -1,44 +1,47 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'generator_spec'
|
|
3
|
-
require 'generators/active_record/aasm_generator'
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
if defined?(ActiveRecord)
|
|
4
|
+
require 'generator_spec'
|
|
5
|
+
require 'generators/active_record/aasm_generator'
|
|
6
|
+
|
|
7
|
+
describe ActiveRecord::Generators::AASMGenerator, type: :generator do
|
|
8
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
|
9
|
+
|
|
10
|
+
before(:all) do
|
|
11
|
+
prepare_destination
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "creates model with aasm block for default column_name" do
|
|
15
|
+
run_generator %w(user)
|
|
16
|
+
assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "creates model with aasm block for custom column_name" do
|
|
20
|
+
run_generator %w(user state)
|
|
21
|
+
assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "creates model with aasm block for namespaced model" do
|
|
25
|
+
run_generator %w(Admin::User state)
|
|
26
|
+
assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "creates migration for model with aasm_column" do
|
|
30
|
+
run_generator %w(post)
|
|
31
|
+
assert_migration "db/migrate/aasm_create_posts.rb", /create_table(:posts) do |t|\n t.string :aasm_state\n/
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "add aasm_column in existing model" do
|
|
35
|
+
run_generator %w(job)
|
|
36
|
+
assert_file "app/models/job.rb"
|
|
37
|
+
run_generator %w(job)
|
|
38
|
+
assert_migration "db/migrate/add_aasm_state_to_jobs.rb"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "add custom aasm_column in existing model" do
|
|
42
|
+
run_generator %w(job state)
|
|
43
|
+
assert_migration "db/migrate/add_state_to_jobs.rb"
|
|
44
|
+
end
|
|
7
45
|
|
|
8
|
-
before(:all) do
|
|
9
|
-
prepare_destination
|
|
10
46
|
end
|
|
11
|
-
|
|
12
|
-
it "creates model with aasm block for default column_name" do
|
|
13
|
-
run_generator %w(user)
|
|
14
|
-
assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "creates model with aasm block for custom column_name" do
|
|
18
|
-
run_generator %w(user state)
|
|
19
|
-
assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it "creates model with aasm block for namespaced model" do
|
|
23
|
-
run_generator %w(Admin::User state)
|
|
24
|
-
assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "creates migration for model with aasm_column" do
|
|
28
|
-
run_generator %w(post)
|
|
29
|
-
assert_migration "db/migrate/aasm_create_posts.rb", /create_table(:posts) do |t|\n t.string :aasm_state\n/
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "add aasm_column in existing model" do
|
|
33
|
-
run_generator %w(job)
|
|
34
|
-
assert_file "app/models/job.rb"
|
|
35
|
-
run_generator %w(job)
|
|
36
|
-
assert_migration "db/migrate/add_aasm_state_to_jobs.rb"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "add custom aasm_column in existing model" do
|
|
40
|
-
run_generator %w(job state)
|
|
41
|
-
assert_migration "db/migrate/add_state_to_jobs.rb"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
47
|
end
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'generator_spec'
|
|
3
|
-
require 'generators/mongoid/aasm_generator'
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
require
|
|
3
|
+
if defined?(Mongoid::Document)
|
|
4
|
+
require 'generator_spec'
|
|
5
|
+
require 'generators/mongoid/aasm_generator'
|
|
7
6
|
|
|
8
7
|
describe Mongoid::Generators::AASMGenerator, type: :generator do
|
|
9
8
|
destination File.expand_path("../../../tmp", __FILE__)
|
|
@@ -28,6 +27,5 @@ begin
|
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
end
|
|
31
|
-
|
|
32
|
-
puts "Not running Mongoid specs because mongoid gem is not installed!!!"
|
|
30
|
+
|
|
33
31
|
end
|
|
@@ -7,7 +7,7 @@ class ComplexActiveRecordExample < ActiveRecord::Base
|
|
|
7
7
|
state :three
|
|
8
8
|
|
|
9
9
|
event :increment do
|
|
10
|
-
transitions :from => :one, :to => :two
|
|
10
|
+
transitions :from => :one, :to => :two, guard: :allowed?
|
|
11
11
|
transitions :from => :two, :to => :three
|
|
12
12
|
end
|
|
13
13
|
event :reset do
|
|
@@ -15,6 +15,10 @@ class ComplexActiveRecordExample < ActiveRecord::Base
|
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def allowed?
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
aasm :right, :column => 'right' do
|
|
19
23
|
state :alpha, :initial => true
|
|
20
24
|
state :beta
|
|
@@ -43,6 +43,7 @@ module Callbacks
|
|
|
43
43
|
:before => :before_event,
|
|
44
44
|
:after => :after_event,
|
|
45
45
|
:guard => :event_guard,
|
|
46
|
+
:before_success => :event_before_success,
|
|
46
47
|
:ensure => :ensure_event do
|
|
47
48
|
transitions :to => :closed, :from => [:open],
|
|
48
49
|
:guard => :transition_guard,
|
|
@@ -78,6 +79,8 @@ module Callbacks
|
|
|
78
79
|
def event_guard; log('event_guard'); !@fail_event_guard; end
|
|
79
80
|
def transition_guard; log('transition_guard'); !@fail_transition_guard; end
|
|
80
81
|
|
|
82
|
+
def event_before_success; log('event_before_success'); end
|
|
83
|
+
|
|
81
84
|
def after_transition; log('after_transition'); end
|
|
82
85
|
def after_all_transitions; log('after_all_transitions'); end
|
|
83
86
|
|
|
@@ -86,8 +89,8 @@ module Callbacks
|
|
|
86
89
|
def after_event; log('after_event'); end
|
|
87
90
|
def after_all_events; log('after_all_events'); end
|
|
88
91
|
|
|
89
|
-
def after_transition;
|
|
90
|
-
def success_transition;
|
|
92
|
+
def after_transition; log('after_transition'); end
|
|
93
|
+
def success_transition; log('transition_success'); end
|
|
91
94
|
|
|
92
95
|
def ensure_event; log('ensure'); end
|
|
93
96
|
def ensure_on_all_events; log('ensure'); end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class GuardianWithoutFromSpecified
|
|
2
|
+
include AASM
|
|
3
|
+
|
|
4
|
+
aasm do
|
|
5
|
+
state :alpha, :initial => true
|
|
6
|
+
state :beta
|
|
7
|
+
state :gamma
|
|
8
|
+
|
|
9
|
+
event :use_guards_where_the_first_fails do
|
|
10
|
+
transitions :to => :beta, :guard => :fail
|
|
11
|
+
transitions :to => :gamma, :guard => :succeed
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def fail; false; end
|
|
17
|
+
def succeed; true; end
|
|
18
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class InvalidPersistorMongoid
|
|
2
|
+
include Mongoid::Document
|
|
3
|
+
include AASM
|
|
4
|
+
|
|
5
|
+
field :name
|
|
6
|
+
field :status
|
|
7
|
+
|
|
8
|
+
aasm :left, column: :status, skip_validation_on_save: true do
|
|
9
|
+
state :sleeping, :initial => true
|
|
10
|
+
state :running
|
|
11
|
+
event :run do
|
|
12
|
+
transitions :to => :running, :from => :sleeping
|
|
13
|
+
end
|
|
14
|
+
event :sleep do
|
|
15
|
+
transitions :to => :sleeping, :from => :running
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
validates_presence_of :name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class MultipleInvalidPersistorMongoid
|
|
22
|
+
include Mongoid::Document
|
|
23
|
+
include AASM
|
|
24
|
+
|
|
25
|
+
field :name
|
|
26
|
+
field :status
|
|
27
|
+
|
|
28
|
+
aasm :left, column: :status, skip_validation_on_save: true do
|
|
29
|
+
state :sleeping, :initial => true
|
|
30
|
+
state :running
|
|
31
|
+
event :run do
|
|
32
|
+
transitions :to => :running, :from => :sleeping
|
|
33
|
+
end
|
|
34
|
+
event :sleep do
|
|
35
|
+
transitions :to => :sleeping, :from => :running
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
validates_presence_of :name
|
|
39
|
+
end
|