aasm 4.11.0 → 4.12.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 +4 -4
- data/.travis.yml +16 -17
- data/Appraisals +44 -0
- data/CHANGELOG.md +24 -1
- data/CONTRIBUTING.md +24 -0
- data/Gemfile +4 -21
- data/README.md +81 -34
- data/Rakefile +6 -1
- data/TESTING.md +25 -0
- data/aasm.gemspec +5 -2
- data/gemfiles/rails_3.2.gemfile +13 -0
- data/gemfiles/rails_4.0.gemfile +8 -9
- data/gemfiles/rails_4.2.gemfile +9 -9
- data/gemfiles/rails_4.2_mongoid_5.gemfile +5 -9
- data/gemfiles/rails_5.0.gemfile +7 -16
- data/lib/aasm/aasm.rb +9 -3
- data/lib/aasm/base.rb +3 -1
- data/lib/aasm/configuration.rb +4 -0
- data/lib/aasm/core/event.rb +19 -9
- data/lib/aasm/core/state.rb +7 -0
- data/lib/aasm/core/transition.rb +9 -0
- data/lib/aasm/instance_base.rb +8 -8
- data/lib/aasm/persistence/active_record_persistence.rb +1 -1
- data/lib/aasm/persistence/base.rb +3 -3
- data/lib/aasm/persistence/mongoid_persistence.rb +48 -9
- 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/aasm_generator.rb +1 -1
- data/lib/motion-aasm.rb +0 -1
- data/spec/en.yml +3 -0
- data/spec/generators/active_record_generator_spec.rb +42 -34
- data/spec/generators/mongoid_generator_spec.rb +4 -6
- 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/active_record/simple_new_dsl.rb +2 -2
- data/spec/models/{transactor.rb → active_record/transactor.rb} +0 -2
- data/spec/models/{validator.rb → active_record/validator.rb} +6 -3
- data/spec/models/callbacks/basic.rb +5 -2
- data/spec/models/guard_with_params.rb +24 -0
- data/spec/models/guard_with_params_multiple.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/simple_mongoid.rb +2 -2
- data/spec/models/mongoid/validator_mongoid.rb +100 -0
- data/spec/models/multi_transitioner.rb +10 -0
- data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
- data/spec/models/parametrised_event.rb +7 -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 +7 -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_with_params_multiple_spec.rb +10 -0
- data/spec/unit/guard_with_params_spec.rb +14 -0
- data/spec/unit/inspection_spec.rb +5 -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/override_warning_spec.rb +8 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +452 -445
- data/spec/unit/persistence/active_record_persistence_spec.rb +523 -490
- 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 +87 -10
- data/spec/unit/persistence/mongoid_persistence_spec.rb +89 -10
- data/spec/unit/persistence/redis_persistence_spec.rb +3 -7
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +4 -9
- data/spec/unit/persistence/sequel_persistence_spec.rb +4 -9
- 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
- metadata +77 -32
- data/gemfiles/rails_3.2_stable.gemfile +0 -15
- data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -17
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -18
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
- data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +0 -37
- 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 -146
- data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -93
- /data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
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.
|
|
@@ -112,12 +123,8 @@ module AASM::Core
|
|
|
112
123
|
|
|
113
124
|
def _fire(obj, options={}, to_state=nil, *args)
|
|
114
125
|
result = options[:test_only] ? false : nil
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return result if transitions.size == 0
|
|
118
|
-
else
|
|
119
|
-
transitions = @transitions
|
|
120
|
-
end
|
|
126
|
+
transitions = @transitions.select { |t| t.from == obj.aasm(state_machine.name).current_state || t.from == nil}
|
|
127
|
+
return result if transitions.size == 0
|
|
121
128
|
|
|
122
129
|
# If to_state is not nil it either contains a potential
|
|
123
130
|
# to_state or an arg
|
|
@@ -126,16 +133,19 @@ module AASM::Core
|
|
|
126
133
|
args.unshift(to_state)
|
|
127
134
|
to_state = nil
|
|
128
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
|
|
129
138
|
end
|
|
130
139
|
|
|
131
140
|
transitions.each do |transition|
|
|
132
141
|
next if to_state and !Array(transition.to).include?(to_state)
|
|
133
|
-
if (options.key?(:may_fire) &&
|
|
142
|
+
if (options.key?(:may_fire) && transition.eql?(options[:may_fire])) ||
|
|
134
143
|
(!options.key?(:may_fire) && transition.allowed?(obj, *args))
|
|
135
|
-
|
|
144
|
+
|
|
136
145
|
if options[:test_only]
|
|
137
|
-
|
|
146
|
+
result = transition
|
|
138
147
|
else
|
|
148
|
+
result = to_state || Array(transition.to).first
|
|
139
149
|
Array(transition.to).each {|to| @valid_transitions[to] = transition }
|
|
140
150
|
transition.execute(obj, *args)
|
|
141
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)
|
data/lib/aasm/instance_base.rb
CHANGED
|
@@ -33,9 +33,9 @@ module AASM
|
|
|
33
33
|
AASM::Localizer.new.human_state_name(@instance.class, state_object_for_name(current_state))
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
def states(options={})
|
|
36
|
+
def states(options={}, *args)
|
|
37
37
|
if options.has_key?(:permitted)
|
|
38
|
-
selected_events = events(:permitted => options[:permitted])
|
|
38
|
+
selected_events = events({:permitted => options[:permitted]}, *args)
|
|
39
39
|
# An array of arrays. Each inner array represents the transitions that
|
|
40
40
|
# transition from the current state for an event
|
|
41
41
|
event_transitions = selected_events.map {|e| e.transitions_from_state(current_state) }
|
|
@@ -45,10 +45,10 @@ module AASM
|
|
|
45
45
|
return nil if transitions.empty?
|
|
46
46
|
|
|
47
47
|
# Return the :to state of the first transition that is allowed (or not) or nil
|
|
48
|
-
if options[:permitted]
|
|
49
|
-
transition = transitions.find { |t| t.allowed?(@instance) }
|
|
48
|
+
if options[:permitted]
|
|
49
|
+
transition = transitions.find { |t| t.allowed?(@instance, *args) }
|
|
50
50
|
else
|
|
51
|
-
transition = transitions.find { |t| !t.allowed?(@instance) }
|
|
51
|
+
transition = transitions.find { |t| !t.allowed?(@instance, *args) }
|
|
52
52
|
end
|
|
53
53
|
transition ? transition.to : nil
|
|
54
54
|
end.flatten.compact.uniq
|
|
@@ -60,7 +60,7 @@ module AASM
|
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
def events(options={})
|
|
63
|
+
def events(options={}, *args)
|
|
64
64
|
state = options[:state] || current_state
|
|
65
65
|
events = @instance.class.aasm(@name).events.select {|e| e.transitions_from_state?(state) }
|
|
66
66
|
|
|
@@ -71,9 +71,9 @@ module AASM
|
|
|
71
71
|
# filters the results of events_for_current_state so that only those that
|
|
72
72
|
# are really currently possible (given transition guards) are shown.
|
|
73
73
|
if options[:permitted]
|
|
74
|
-
events.select! { |e| @instance.send("may_#{e.name}?") }
|
|
74
|
+
events.select! { |e| @instance.send("may_#{e.name}?", *args) }
|
|
75
75
|
else
|
|
76
|
-
events.select! { |e| !@instance.send("may_#{e.name}?") }
|
|
76
|
+
events.select! { |e| !@instance.send("may_#{e.name}?", *args) }
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -103,7 +103,7 @@ module AASM
|
|
|
103
103
|
private
|
|
104
104
|
|
|
105
105
|
def aasm_update_column(name, value)
|
|
106
|
-
self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
|
|
106
|
+
self.class.unscoped.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def aasm_rollback(name, old_value)
|
|
@@ -53,9 +53,9 @@ module AASM
|
|
|
53
53
|
|
|
54
54
|
class Base
|
|
55
55
|
# make sure to create a (named) scope for each state
|
|
56
|
-
def state_with_scope(
|
|
57
|
-
state_without_scope(
|
|
58
|
-
create_scope(name) if create_scope?(name)
|
|
56
|
+
def state_with_scope(*args)
|
|
57
|
+
names = state_without_scope(*args)
|
|
58
|
+
names.each { |name| create_scope(name) if create_scope?(name) }
|
|
59
59
|
end
|
|
60
60
|
alias_method :state_without_scope, :state
|
|
61
61
|
alias_method :state, :state_with_scope
|
|
@@ -50,8 +50,7 @@ module AASM
|
|
|
50
50
|
|
|
51
51
|
module InstanceMethods
|
|
52
52
|
|
|
53
|
-
# Writes <tt>state</tt> to the state
|
|
54
|
-
# using update_attribute (which bypasses validation)
|
|
53
|
+
# Writes <tt>state</tt> to the state field and persists it to the database
|
|
55
54
|
#
|
|
56
55
|
# foo = Foo.find(1)
|
|
57
56
|
# foo.aasm.current_state # => :opened
|
|
@@ -62,17 +61,24 @@ module AASM
|
|
|
62
61
|
# NOTE: intended to be called from an event
|
|
63
62
|
def aasm_write_state(state, name=:default)
|
|
64
63
|
old_value = read_attribute(self.class.aasm(name).attribute_name)
|
|
65
|
-
|
|
64
|
+
aasm_write_attribute(state, name)
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
success = if aasm_skipping_validations(name)
|
|
67
|
+
value = aasm_raw_attribute_value(state, name)
|
|
68
|
+
aasm_update_column(name, value)
|
|
69
|
+
else
|
|
70
|
+
self.save
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
unless success
|
|
74
|
+
aasm_rollback(name, old_value)
|
|
75
|
+
raise Mongoid::Errors::Validations.new(self) if aasm_whiny_persistence(name)
|
|
70
76
|
end
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
success
|
|
73
79
|
end
|
|
74
80
|
|
|
75
|
-
# Writes <tt>state</tt> to the state
|
|
81
|
+
# Writes <tt>state</tt> to the state field, but does not persist it to the database
|
|
76
82
|
#
|
|
77
83
|
# foo = Foo.find(1)
|
|
78
84
|
# foo.aasm.current_state # => :opened
|
|
@@ -85,11 +91,44 @@ module AASM
|
|
|
85
91
|
#
|
|
86
92
|
# NOTE: intended to be called from an event
|
|
87
93
|
def aasm_write_state_without_persistence(state, name=:default)
|
|
88
|
-
|
|
94
|
+
aasm_write_attribute(state, name)
|
|
89
95
|
end
|
|
90
96
|
|
|
91
97
|
private
|
|
92
98
|
|
|
99
|
+
def aasm_update_column(name, value)
|
|
100
|
+
attribute_name = self.class.aasm(name).attribute_name
|
|
101
|
+
|
|
102
|
+
if Mongoid::VERSION.to_f >= 4
|
|
103
|
+
set(Hash[attribute_name, value])
|
|
104
|
+
else
|
|
105
|
+
set(attribute_name, value)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def aasm_rollback(name, old_value)
|
|
112
|
+
write_attribute(self.class.aasm(name).attribute_name, old_value)
|
|
113
|
+
false
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def aasm_skipping_validations(state_machine_name)
|
|
117
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def aasm_whiny_persistence(state_machine_name)
|
|
121
|
+
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def aasm_write_attribute(state, name=:default)
|
|
125
|
+
write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def aasm_raw_attribute_value(state, _name=:default)
|
|
129
|
+
state.to_s
|
|
130
|
+
end
|
|
131
|
+
|
|
93
132
|
# Ensures that if the aasm_state column is nil and the record is new
|
|
94
133
|
# that the initial state gets populated before validation on create
|
|
95
134
|
#
|
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
|
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
|
12
12
|
|
|
13
13
|
def copy_aasm_migration
|
|
14
14
|
if model_exists?
|
|
15
|
-
migration_template "migration_existing.rb", "db/migrate/
|
|
15
|
+
migration_template "migration_existing.rb", "db/migrate/add_#{column_name}_to_#{table_name}.rb"
|
|
16
16
|
else
|
|
17
17
|
migration_template "migration.rb", "db/migrate/aasm_create_#{table_name}.rb"
|
|
18
18
|
end
|
data/lib/motion-aasm.rb
CHANGED
|
@@ -13,7 +13,6 @@ exclude_files = [
|
|
|
13
13
|
'aasm/rspec.*',
|
|
14
14
|
'aasm/persistence/active_record_persistence.rb',
|
|
15
15
|
'aasm/persistence/dynamoid_persistence.rb',
|
|
16
|
-
'aasm/persistence/mongo_mapper_persistence.rb',
|
|
17
16
|
'aasm/persistence/mongoid_persistence.rb',
|
|
18
17
|
'aasm/persistence/sequel_persistence.rb',
|
|
19
18
|
'aasm/persistence/redis_persistence.rb'
|
data/spec/en.yml
CHANGED
|
@@ -1,39 +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
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
|
|
@@ -2,7 +2,7 @@ class SimpleNewDsl < ActiveRecord::Base
|
|
|
2
2
|
include AASM
|
|
3
3
|
aasm :column => :status
|
|
4
4
|
aasm do
|
|
5
|
-
state :unknown_scope
|
|
5
|
+
state :unknown_scope, :another_unknown_scope
|
|
6
6
|
state :new
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -11,7 +11,7 @@ class MultipleSimpleNewDsl < ActiveRecord::Base
|
|
|
11
11
|
include AASM
|
|
12
12
|
aasm :left, :column => :status
|
|
13
13
|
aasm :left do
|
|
14
|
-
state :unknown_scope
|
|
14
|
+
state :unknown_scope, :another_unknown_scope
|
|
15
15
|
state :new
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
require 'active_record'
|
|
2
|
-
|
|
3
1
|
class Validator < ActiveRecord::Base
|
|
4
2
|
attr_accessor :after_all_transactions_performed,
|
|
5
3
|
:after_transaction_performed_on_fail,
|
|
6
4
|
:after_transaction_performed_on_run,
|
|
7
5
|
:before_all_transactions_performed,
|
|
8
6
|
:before_transaction_performed_on_fail,
|
|
9
|
-
:before_transaction_performed_on_run
|
|
7
|
+
:before_transaction_performed_on_run,
|
|
8
|
+
:invalid
|
|
9
|
+
|
|
10
|
+
validate do |model|
|
|
11
|
+
errors.add(:validator, "invalid") if invalid
|
|
12
|
+
end
|
|
10
13
|
|
|
11
14
|
include AASM
|
|
12
15
|
|
|
@@ -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,24 @@
|
|
|
1
|
+
class GuardWithParams
|
|
2
|
+
include AASM
|
|
3
|
+
aasm do
|
|
4
|
+
state :new, :reviewed, :finalized
|
|
5
|
+
|
|
6
|
+
event :mark_as_reviewed do
|
|
7
|
+
transitions :from => :new, :to => :reviewed, :guards => [:user_is_manager?]
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def user_is_manager?(user)
|
|
12
|
+
ok = false
|
|
13
|
+
if user && user.has_role?(:manager)
|
|
14
|
+
ok = true
|
|
15
|
+
end
|
|
16
|
+
return ok
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class GuardParamsClass
|
|
21
|
+
def has_role?(role)
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class GuardWithParamsMultiple
|
|
2
|
+
include AASM
|
|
3
|
+
aasm(:left) do
|
|
4
|
+
state :new, :reviewed, :finalized
|
|
5
|
+
|
|
6
|
+
event :mark_as_reviewed do
|
|
7
|
+
transitions :from => :new, :to => :reviewed, :guards => [:user_is_manager?]
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def user_is_manager?(user)
|
|
12
|
+
ok = false
|
|
13
|
+
if user.has_role? :manager
|
|
14
|
+
ok = true
|
|
15
|
+
end
|
|
16
|
+
return ok
|
|
17
|
+
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
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class SilentPersistorMongoid
|
|
2
|
+
include Mongoid::Document
|
|
3
|
+
include AASM
|
|
4
|
+
|
|
5
|
+
field :name
|
|
6
|
+
field :status
|
|
7
|
+
|
|
8
|
+
aasm :left, column: :status, whiny_persistence: false 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 MultipleSilentPersistorMongoid
|
|
22
|
+
include Mongoid::Document
|
|
23
|
+
include AASM
|
|
24
|
+
|
|
25
|
+
field :name
|
|
26
|
+
field :status
|
|
27
|
+
|
|
28
|
+
aasm :left, column: :status, whiny_persistence: false 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
|