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
data/gemfiles/rails_5.0.gemfile
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
1
3
|
source "https://rubygems.org"
|
|
2
4
|
|
|
3
|
-
gem "sqlite3",
|
|
4
|
-
gem 'rubysl', :platforms => :rbx
|
|
5
|
-
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
6
|
-
gem "jruby-openssl", :platforms => :jruby
|
|
5
|
+
gem "sqlite3", :platforms => :ruby
|
|
7
6
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
8
|
-
|
|
9
|
-
gem "
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
gem 'sequel'
|
|
15
|
-
|
|
16
|
-
# dynamoid is not yet Rails 5 compatible
|
|
17
|
-
# gem 'dynamoid', '~> 1', :platforms => :ruby
|
|
18
|
-
|
|
19
|
-
gem 'aws-sdk', '~>2', :platforms => :ruby
|
|
7
|
+
gem "rails", "5.0.0"
|
|
8
|
+
gem "mongoid", "~>6.0"
|
|
9
|
+
gem "sequel"
|
|
10
|
+
gem "aws-sdk", "~>2", :platforms => :ruby
|
|
11
|
+
gem "redis-objects"
|
|
20
12
|
|
|
21
13
|
gemspec :path => "../"
|
data/lib/aasm/aasm.rb
CHANGED
|
@@ -42,7 +42,7 @@ module AASM
|
|
|
42
42
|
|
|
43
43
|
raise ArgumentError, "The class #{aasm_klass} must inherit from AASM::Base!" unless aasm_klass.ancestors.include?(AASM::Base)
|
|
44
44
|
|
|
45
|
-
@aasm ||=
|
|
45
|
+
@aasm ||= Concurrent::Map.new
|
|
46
46
|
if @aasm[state_machine_name]
|
|
47
47
|
# make sure to use provided options
|
|
48
48
|
options.each do |key, value|
|
|
@@ -67,12 +67,12 @@ module AASM
|
|
|
67
67
|
unless AASM::StateMachineStore.fetch(self.class, true).machine(name)
|
|
68
68
|
raise AASM::UnknownStateMachineError.new("There is no state machine with the name '#{name}' defined in #{self.class.name}!")
|
|
69
69
|
end
|
|
70
|
-
@aasm ||=
|
|
70
|
+
@aasm ||= Concurrent::Map.new
|
|
71
71
|
@aasm[name.to_sym] ||= AASM::InstanceBase.new(self, name.to_sym)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def initialize_dup(other)
|
|
75
|
-
@aasm =
|
|
75
|
+
@aasm = Concurrent::Map.new
|
|
76
76
|
super
|
|
77
77
|
end
|
|
78
78
|
|
|
@@ -150,6 +150,7 @@ private
|
|
|
150
150
|
persist_successful = aasm(state_machine_name).set_current_state_with_persistence(new_state_name)
|
|
151
151
|
if persist_successful
|
|
152
152
|
yield if block_given?
|
|
153
|
+
event.fire_callbacks(:before_success, self)
|
|
153
154
|
event.fire_transition_callbacks(self, *process_args(event, old_state.name, *args))
|
|
154
155
|
event.fire_callbacks(:success, self)
|
|
155
156
|
end
|
|
@@ -158,6 +159,11 @@ private
|
|
|
158
159
|
yield if block_given?
|
|
159
160
|
end
|
|
160
161
|
|
|
162
|
+
binding_event = event.options[:binding_event]
|
|
163
|
+
if binding_event
|
|
164
|
+
__send__("#{binding_event}#{'!' if persist}")
|
|
165
|
+
end
|
|
166
|
+
|
|
161
167
|
if persist_successful
|
|
162
168
|
old_state.fire_callbacks(:after_exit, self,
|
|
163
169
|
*process_args(event, aasm(state_machine_name).current_state, *args))
|
data/lib/aasm/base.rb
CHANGED
|
@@ -130,6 +130,14 @@ module AASM
|
|
|
130
130
|
aasm(aasm_name).current_event = event
|
|
131
131
|
aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
|
|
132
132
|
end
|
|
133
|
+
|
|
134
|
+
# Create aliases for the event methods. Keep the old names to maintain backwards compatibility.
|
|
135
|
+
if namespace?
|
|
136
|
+
klass.send(:alias_method, "may_#{name}_#{namespace}?", "may_#{name}?")
|
|
137
|
+
klass.send(:alias_method, "#{name}_#{namespace}!", "#{name}!")
|
|
138
|
+
klass.send(:alias_method, "#{name}_#{namespace}", name)
|
|
139
|
+
end
|
|
140
|
+
|
|
133
141
|
end
|
|
134
142
|
|
|
135
143
|
def after_all_transitions(*callbacks, &block)
|
|
@@ -208,7 +216,9 @@ module AASM
|
|
|
208
216
|
klass.defined_enums.values.any?{ |methods|
|
|
209
217
|
methods.keys{| enum | enum + '?' == method_name }
|
|
210
218
|
})
|
|
211
|
-
|
|
219
|
+
unless AASM::Configuration.hide_warnings
|
|
220
|
+
@state_machine.config.logger.warn "#{klass.name}: overriding method '#{method_name}'!"
|
|
221
|
+
end
|
|
212
222
|
end
|
|
213
223
|
|
|
214
224
|
klass.send(:define_method, method_name, method_definition)
|
data/lib/aasm/configuration.rb
CHANGED
data/lib/aasm/core/event.rb
CHANGED
|
@@ -22,10 +22,21 @@ module AASM::Core
|
|
|
22
22
|
:before_transaction,
|
|
23
23
|
:ensure,
|
|
24
24
|
:error,
|
|
25
|
+
:before_success,
|
|
25
26
|
:success,
|
|
26
27
|
], &block) if block
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
# called internally by Ruby 1.9 after clone()
|
|
31
|
+
def initialize_copy(orig)
|
|
32
|
+
super
|
|
33
|
+
@transitions = @transitions.collect { |transition| transition.clone }
|
|
34
|
+
@guards = @guards.dup
|
|
35
|
+
@unless = @unless.dup
|
|
36
|
+
@options = {}
|
|
37
|
+
orig.options.each_pair { |name, setting| @options[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
|
|
38
|
+
end
|
|
39
|
+
|
|
29
40
|
# a neutered version of fire - it doesn't actually fire the event, it just
|
|
30
41
|
# executes the transition guards to determine if a transition is even
|
|
31
42
|
# an option given current conditions.
|
|
@@ -85,7 +96,7 @@ module AASM::Core
|
|
|
85
96
|
@transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
|
|
86
97
|
end
|
|
87
98
|
# Create a transition if :to is specified without :from (transitions from ANY state)
|
|
88
|
-
if
|
|
99
|
+
if !definitions[:from] && definitions[:to]
|
|
89
100
|
@transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions), &block)
|
|
90
101
|
end
|
|
91
102
|
end
|
|
@@ -122,16 +133,19 @@ module AASM::Core
|
|
|
122
133
|
args.unshift(to_state)
|
|
123
134
|
to_state = nil
|
|
124
135
|
end
|
|
136
|
+
else
|
|
137
|
+
args.unshift(nil) if args.nil? || args.empty? # If single arg given which is nil, push it back to args
|
|
125
138
|
end
|
|
126
139
|
|
|
127
140
|
transitions.each do |transition|
|
|
128
141
|
next if to_state and !Array(transition.to).include?(to_state)
|
|
129
|
-
if (options.key?(:may_fire) &&
|
|
142
|
+
if (options.key?(:may_fire) && transition.eql?(options[:may_fire])) ||
|
|
130
143
|
(!options.key?(:may_fire) && transition.allowed?(obj, *args))
|
|
131
|
-
|
|
144
|
+
|
|
132
145
|
if options[:test_only]
|
|
133
|
-
|
|
146
|
+
result = transition
|
|
134
147
|
else
|
|
148
|
+
result = to_state || Array(transition.to).first
|
|
135
149
|
Array(transition.to).each {|to| @valid_transitions[to] = transition }
|
|
136
150
|
transition.execute(obj, *args)
|
|
137
151
|
end
|
data/lib/aasm/core/state.rb
CHANGED
|
@@ -9,6 +9,13 @@ module AASM::Core
|
|
|
9
9
|
update(options)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
# called internally by Ruby 1.9 after clone()
|
|
13
|
+
def initialize_copy(orig)
|
|
14
|
+
super
|
|
15
|
+
@options = {}
|
|
16
|
+
orig.options.each_pair { |name, setting| @options[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
|
|
17
|
+
end
|
|
18
|
+
|
|
12
19
|
def ==(state)
|
|
13
20
|
if state.is_a? Symbol
|
|
14
21
|
name == state
|
data/lib/aasm/core/transition.rb
CHANGED
|
@@ -28,6 +28,15 @@ module AASM::Core
|
|
|
28
28
|
@opts = opts
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# called internally by Ruby 1.9 after clone()
|
|
32
|
+
def initialize_copy(orig)
|
|
33
|
+
super
|
|
34
|
+
@guards = @guards.dup
|
|
35
|
+
@unless = @unless.dup
|
|
36
|
+
@opts = {}
|
|
37
|
+
orig.opts.each_pair { |name, setting| @opts[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
|
|
38
|
+
end
|
|
39
|
+
|
|
31
40
|
def allowed?(obj, *args)
|
|
32
41
|
invoke_callbacks_compatible_with_guard(@guards, obj, args, :guard => true) &&
|
|
33
42
|
invoke_callbacks_compatible_with_guard(@unless, obj, args, :unless => true)
|
|
@@ -60,7 +69,7 @@ module AASM::Core
|
|
|
60
69
|
|
|
61
70
|
case code
|
|
62
71
|
when Symbol, String
|
|
63
|
-
result = (record.__send__(:method, code.to_sym).arity
|
|
72
|
+
result = (record.__send__(:method, code.to_sym).arity != 0 ? record.__send__(code, *args) : record.__send__(code))
|
|
64
73
|
failures << code unless result
|
|
65
74
|
result
|
|
66
75
|
when Proc
|
data/lib/aasm/instance_base.rb
CHANGED
|
@@ -14,7 +14,6 @@ module AASM
|
|
|
14
14
|
|
|
15
15
|
def current_state=(state)
|
|
16
16
|
@instance.aasm_write_state_without_persistence(state, @name)
|
|
17
|
-
# @current_state = state
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def enter_initial_state
|
|
@@ -22,7 +21,6 @@ module AASM
|
|
|
22
21
|
state_object = state_object_for_name(state_name)
|
|
23
22
|
|
|
24
23
|
state_object.fire_callbacks(:before_enter, @instance)
|
|
25
|
-
# state_object.fire_callbacks(:enter, @instance)
|
|
26
24
|
self.current_state = state_name
|
|
27
25
|
state_object.fire_callbacks(:after_enter, @instance)
|
|
28
26
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Minitest::Assertions
|
|
2
|
+
def assert_event_allowed(object, event, options = {})
|
|
3
|
+
state_machine_name = options.fetch(:on, :default)
|
|
4
|
+
assert object.aasm(state_machine_name).may_fire_event?(event),
|
|
5
|
+
"Expected that the event :#{event} would be allowed (on :#{state_machine_name})"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def refute_event_allowed(object, event, options = {})
|
|
9
|
+
state_machine_name = options.fetch(:on, :default)
|
|
10
|
+
refute object.aasm(state_machine_name).may_fire_event?(event),
|
|
11
|
+
"Expected that the event :#{event} would not be allowed (on :#{state_machine_name})"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Minitest::Assertions
|
|
2
|
+
def assert_transition_to_allowed(object, to_state, options = {})
|
|
3
|
+
state_machine_name = options.fetch(:on, :default)
|
|
4
|
+
assert object.aasm(state_machine_name).states(permitted: true).include?(to_state),
|
|
5
|
+
"Expected that the state :#{to_state} would be reachable (on :#{state_machine_name})"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def refute_transition_to_allowed(object, to_state, options = {})
|
|
9
|
+
state_machine_name = options.fetch(:on, :default)
|
|
10
|
+
refute object.aasm(state_machine_name).states(permitted: true).include?(to_state),
|
|
11
|
+
"Expected that the state :#{to_state} would be reachable (on :#{state_machine_name})"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Minitest::Assertions
|
|
2
|
+
def assert_have_state(object, state, options = {})
|
|
3
|
+
state_machine_name = options.fetch(:on, :default)
|
|
4
|
+
assert object.aasm(state_machine_name).current_state == state,
|
|
5
|
+
"Expected that :#{object.aasm(state_machine_name).current_state} would be :#{state} (on :#{state_machine_name})"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def refute_have_state(object, state, options = {})
|
|
9
|
+
state_machine_name = options.fetch(:on, :default)
|
|
10
|
+
refute object.aasm(state_machine_name).current_state == state,
|
|
11
|
+
"Expected that :#{object.aasm(state_machine_name).current_state} would be :#{state} (on :#{state_machine_name})"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Minitest::Assertions
|
|
2
|
+
def assert_transitions_from(object, from_state, *args)
|
|
3
|
+
options = args.first
|
|
4
|
+
options[:on] ||= :default
|
|
5
|
+
assert _transitions_from?(object, from_state, args, options),
|
|
6
|
+
"Expected transition state to :#{options[:to]} from :#{from_state} on event :#{options[:on_event]}, (on :#{options[:on]})"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def refute_transitions_from(object, from_state, *args)
|
|
10
|
+
options = args.first
|
|
11
|
+
options[:on] ||= :default
|
|
12
|
+
refute _transitions_from?(object, from_state, args, options),
|
|
13
|
+
"Expected transition state to :#{options[:to]} from :#{from_state} on event :#{options[:on_event]}, (on :#{options[:on]})"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def _transitions_from?(object, from_state, args, options)
|
|
17
|
+
state_machine_name = options[:on]
|
|
18
|
+
object.aasm(state_machine_name).current_state = from_state.to_sym
|
|
19
|
+
object.send(options[:on_event], *args) && options[:to].to_sym == object.aasm(state_machine_name).current_state
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'aasm/minitest'
|
|
2
|
+
|
|
3
|
+
module Minitest::Expectations
|
|
4
|
+
AASM.infect_an_assertion :assert_transitions_from, :must_transition_from, :do_not_flip
|
|
5
|
+
AASM.infect_an_assertion :refute_transitions_from, :wont_transition_from, :do_not_flip
|
|
6
|
+
|
|
7
|
+
AASM.infect_an_assertion :assert_transition_to_allowed, :must_allow_transition_to, :do_not_flip
|
|
8
|
+
AASM.infect_an_assertion :refute_transition_to_allowed, :wont_allow_transition_to, :do_not_flip
|
|
9
|
+
|
|
10
|
+
AASM.infect_an_assertion :assert_have_state, :must_have_state, :do_not_flip
|
|
11
|
+
AASM.infect_an_assertion :refute_have_state, :wont_have_state, :do_not_flip
|
|
12
|
+
|
|
13
|
+
AASM.infect_an_assertion :assert_event_allowed, :must_allow_event, :do_not_flip
|
|
14
|
+
AASM.infect_an_assertion :refute_event_allowed, :wont_allow_event, :do_not_flip
|
|
15
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'aasm/persistence/orm'
|
|
1
2
|
module AASM
|
|
2
3
|
module Persistence
|
|
3
4
|
module ActiveRecordPersistence
|
|
@@ -28,6 +29,7 @@ module AASM
|
|
|
28
29
|
#
|
|
29
30
|
def self.included(base)
|
|
30
31
|
base.send(:include, AASM::Persistence::Base)
|
|
32
|
+
base.send(:include, AASM::Persistence::ORM)
|
|
31
33
|
base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
|
|
32
34
|
base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
|
|
33
35
|
|
|
@@ -56,67 +58,41 @@ module AASM
|
|
|
56
58
|
|
|
57
59
|
module InstanceMethods
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
#
|
|
61
|
-
# foo = Foo.find(1)
|
|
62
|
-
# foo.aasm.current_state # => :opened
|
|
63
|
-
# foo.close!
|
|
64
|
-
# foo.aasm.current_state # => :closed
|
|
65
|
-
# Foo.find(1).aasm.current_state # => :closed
|
|
66
|
-
#
|
|
67
|
-
# NOTE: intended to be called from an event
|
|
68
|
-
def aasm_write_state(state, name=:default)
|
|
69
|
-
old_value = read_attribute(self.class.aasm(name).attribute_name)
|
|
70
|
-
aasm_write_attribute state, name
|
|
71
|
-
|
|
72
|
-
success = if aasm_skipping_validations(name)
|
|
73
|
-
value = aasm_raw_attribute_value(state, name)
|
|
74
|
-
aasm_update_column(name, value)
|
|
75
|
-
else
|
|
76
|
-
self.save
|
|
77
|
-
end
|
|
61
|
+
private
|
|
78
62
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
end
|
|
63
|
+
def aasm_raise_invalid_record
|
|
64
|
+
raise ActiveRecord::RecordInvalid.new(self)
|
|
65
|
+
end
|
|
83
66
|
|
|
84
|
-
|
|
67
|
+
def aasm_save
|
|
68
|
+
self.save
|
|
85
69
|
end
|
|
86
70
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# foo = Foo.find(1)
|
|
90
|
-
# foo.aasm.current_state # => :opened
|
|
91
|
-
# foo.close
|
|
92
|
-
# foo.aasm.current_state # => :closed
|
|
93
|
-
# Foo.find(1).aasm.current_state # => :opened
|
|
94
|
-
# foo.save
|
|
95
|
-
# foo.aasm.current_state # => :closed
|
|
96
|
-
# Foo.find(1).aasm.current_state # => :closed
|
|
97
|
-
#
|
|
98
|
-
# NOTE: intended to be called from an event
|
|
99
|
-
def aasm_write_state_without_persistence(state, name=:default)
|
|
100
|
-
aasm_write_attribute(state, name)
|
|
71
|
+
def aasm_update_column(attribute_name, value)
|
|
72
|
+
self.class.unscoped.where(self.class.primary_key => self.id).update_all(attribute_name => value) == 1
|
|
101
73
|
end
|
|
102
74
|
|
|
103
|
-
|
|
75
|
+
def aasm_read_attribute(name)
|
|
76
|
+
read_attribute(name)
|
|
77
|
+
end
|
|
104
78
|
|
|
105
|
-
def
|
|
106
|
-
|
|
79
|
+
def aasm_write_attribute(name, value)
|
|
80
|
+
write_attribute(name, value)
|
|
107
81
|
end
|
|
108
82
|
|
|
109
|
-
def
|
|
110
|
-
|
|
111
|
-
|
|
83
|
+
def aasm_transaction(requires_new, requires_lock)
|
|
84
|
+
self.class.transaction(:requires_new => requires_new) do
|
|
85
|
+
lock!(requires_lock) if requires_lock
|
|
86
|
+
yield
|
|
87
|
+
end
|
|
112
88
|
end
|
|
113
89
|
|
|
114
90
|
def aasm_enum(name=:default)
|
|
115
91
|
case AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
92
|
+
when false then nil
|
|
93
|
+
when true then aasm_guess_enum_method(name)
|
|
94
|
+
when nil then aasm_guess_enum_method(name) if aasm_column_looks_like_enum(name)
|
|
95
|
+
else AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
|
|
120
96
|
end
|
|
121
97
|
end
|
|
122
98
|
|
|
@@ -131,23 +107,11 @@ module AASM
|
|
|
131
107
|
self.class.aasm(name).attribute_name.to_s.pluralize.to_sym
|
|
132
108
|
end
|
|
133
109
|
|
|
134
|
-
def aasm_skipping_validations(state_machine_name)
|
|
135
|
-
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def aasm_whiny_persistence(state_machine_name)
|
|
139
|
-
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def aasm_write_attribute(state, name=:default)
|
|
143
|
-
write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
|
|
144
|
-
end
|
|
145
|
-
|
|
146
110
|
def aasm_raw_attribute_value(state, name=:default)
|
|
147
111
|
if aasm_enum(name)
|
|
148
112
|
self.class.send(aasm_enum(name))[state]
|
|
149
113
|
else
|
|
150
|
-
|
|
114
|
+
super
|
|
151
115
|
end
|
|
152
116
|
end
|
|
153
117
|
|
|
@@ -179,46 +143,6 @@ module AASM
|
|
|
179
143
|
attribute_names.include?(attribute_name.to_s) && send(attribute_name).blank?
|
|
180
144
|
end
|
|
181
145
|
|
|
182
|
-
def aasm_fire_event(state_machine_name, name, options, *args, &block)
|
|
183
|
-
event = self.class.aasm(state_machine_name).state_machine.events[name]
|
|
184
|
-
|
|
185
|
-
if options[:persist]
|
|
186
|
-
event.fire_callbacks(:before_transaction, self, *args)
|
|
187
|
-
event.fire_global_callbacks(:before_all_transactions, self, *args)
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
begin
|
|
191
|
-
success = if options[:persist]
|
|
192
|
-
self.class.transaction(:requires_new => requires_new?(state_machine_name)) do
|
|
193
|
-
lock!(requires_lock?(state_machine_name)) if requires_lock?(state_machine_name)
|
|
194
|
-
super
|
|
195
|
-
end
|
|
196
|
-
else
|
|
197
|
-
super
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
if options[:persist] && success
|
|
201
|
-
event.fire_callbacks(:after_commit, self, *args)
|
|
202
|
-
event.fire_global_callbacks(:after_all_commits, self, *args)
|
|
203
|
-
end
|
|
204
|
-
ensure
|
|
205
|
-
if options[:persist]
|
|
206
|
-
event.fire_callbacks(:after_transaction, self, *args)
|
|
207
|
-
event.fire_global_callbacks(:after_all_transactions, self, *args)
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
success
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def requires_new?(state_machine_name)
|
|
215
|
-
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_new_transaction
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
def requires_lock?(state_machine_name)
|
|
219
|
-
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_lock
|
|
220
|
-
end
|
|
221
|
-
|
|
222
146
|
def aasm_validate_states
|
|
223
147
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
|
|
224
148
|
unless aasm_skipping_validations(state_machine_name)
|
|
@@ -34,13 +34,17 @@ module AASM
|
|
|
34
34
|
# This allows for nil aasm states - be sure to add validation to your model
|
|
35
35
|
def aasm_read_state(name=:default)
|
|
36
36
|
state = send(self.class.aasm(name).attribute_name)
|
|
37
|
-
if
|
|
38
|
-
|
|
37
|
+
if state.blank?
|
|
38
|
+
aasm_new_record? ? aasm(name).determine_state_name(self.class.aasm(name).initial_state) : nil
|
|
39
39
|
else
|
|
40
|
-
state.
|
|
40
|
+
state.to_sym
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def aasm_new_record?
|
|
45
|
+
new_record?
|
|
46
|
+
end
|
|
47
|
+
|
|
44
48
|
module ClassMethods
|
|
45
49
|
def aasm_column(attribute_name=nil)
|
|
46
50
|
warn "[DEPRECATION] aasm_column is deprecated. Use aasm.attribute_name instead"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'aasm/persistence/orm'
|
|
1
2
|
module AASM
|
|
2
3
|
module Persistence
|
|
3
4
|
module MongoidPersistence
|
|
@@ -30,6 +31,7 @@ module AASM
|
|
|
30
31
|
#
|
|
31
32
|
def self.included(base)
|
|
32
33
|
base.send(:include, AASM::Persistence::Base)
|
|
34
|
+
base.send(:include, AASM::Persistence::ORM)
|
|
33
35
|
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
|
|
34
36
|
base.extend AASM::Persistence::MongoidPersistence::ClassMethods
|
|
35
37
|
|
|
@@ -50,45 +52,37 @@ module AASM
|
|
|
50
52
|
|
|
51
53
|
module InstanceMethods
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# NOTE: intended to be called from an event
|
|
63
|
-
def aasm_write_state(state, name=:default)
|
|
64
|
-
old_value = read_attribute(self.class.aasm(name).attribute_name)
|
|
65
|
-
write_attribute(self.class.aasm(name).attribute_name, state.to_s)
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def aasm_save
|
|
58
|
+
self.save
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def aasm_raise_invalid_record
|
|
62
|
+
raise Mongoid::Errors::Validations.new(self)
|
|
63
|
+
end
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
def aasm_supports_transactions?
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def aasm_update_column(attribute_name, value)
|
|
70
|
+
if Mongoid::VERSION.to_f >= 4
|
|
71
|
+
set(Hash[attribute_name, value])
|
|
72
|
+
else
|
|
73
|
+
set(attribute_name, value)
|
|
70
74
|
end
|
|
71
75
|
|
|
72
76
|
true
|
|
73
77
|
end
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
# foo = Foo.find(1)
|
|
78
|
-
# foo.aasm.current_state # => :opened
|
|
79
|
-
# foo.close
|
|
80
|
-
# foo.aasm.current_state # => :closed
|
|
81
|
-
# Foo.find(1).aasm.current_state # => :opened
|
|
82
|
-
# foo.save
|
|
83
|
-
# foo.aasm.current_state # => :closed
|
|
84
|
-
# Foo.find(1).aasm.current_state # => :closed
|
|
85
|
-
#
|
|
86
|
-
# NOTE: intended to be called from an event
|
|
87
|
-
def aasm_write_state_without_persistence(state, name=:default)
|
|
88
|
-
write_attribute(self.class.aasm(name).attribute_name, state.to_s)
|
|
79
|
+
def aasm_read_attribute(name)
|
|
80
|
+
read_attribute(name)
|
|
89
81
|
end
|
|
90
82
|
|
|
91
|
-
|
|
83
|
+
def aasm_write_attribute(name, value)
|
|
84
|
+
write_attribute(name, value)
|
|
85
|
+
end
|
|
92
86
|
|
|
93
87
|
# Ensures that if the aasm_state column is nil and the record is new
|
|
94
88
|
# that the initial state gets populated before validation on create
|