aasm 4.9.0 → 4.10.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 +9 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +3 -0
- data/README.md +27 -11
- data/gemfiles/rails_4.0.gemfile +1 -0
- data/gemfiles/rails_4.1.gemfile +1 -0
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +1 -0
- data/lib/aasm.rb +3 -1
- data/lib/aasm/aasm.rb +13 -9
- data/lib/aasm/base.rb +67 -28
- data/lib/aasm/configuration.rb +3 -0
- data/lib/aasm/core/event.rb +8 -1
- data/lib/aasm/core/transition.rb +32 -4
- data/lib/aasm/errors.rb +4 -4
- data/lib/aasm/persistence.rb +14 -1
- data/lib/aasm/persistence/active_record_persistence.rb +27 -13
- data/lib/aasm/persistence/base.rb +2 -44
- data/lib/aasm/persistence/core_data_query_persistence.rb +93 -0
- data/lib/aasm/persistence/dynamoid_persistence.rb +2 -4
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +15 -9
- data/lib/aasm/persistence/mongoid_persistence.rb +24 -4
- data/lib/aasm/persistence/redis_persistence.rb +107 -0
- data/lib/aasm/persistence/sequel_persistence.rb +1 -3
- data/lib/aasm/state_machine.rb +1 -9
- data/lib/aasm/state_machine_store.rb +73 -0
- data/lib/aasm/version.rb +1 -1
- data/lib/generators/active_record/templates/migration_existing.rb +2 -6
- data/lib/motion-aasm.rb +35 -0
- data/spec/models/callbacks/basic.rb +12 -2
- data/spec/models/callbacks/guard_within_block.rb +2 -1
- data/spec/models/callbacks/multiple_transitions_transition_guard.rb +2 -1
- data/spec/models/callbacks/with_args.rb +2 -1
- data/spec/models/callbacks/with_state_arg.rb +6 -2
- data/spec/models/mongoid/mongoid_relationships.rb +26 -0
- data/spec/models/namespaced_multiple_example.rb +28 -0
- data/spec/models/parametrised_event.rb +9 -3
- data/spec/models/states_on_one_line_example.rb +8 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/api_spec.rb +20 -0
- data/spec/unit/callbacks_spec.rb +17 -5
- data/spec/unit/event_spec.rb +19 -1
- data/spec/unit/exception_spec.rb +11 -0
- data/spec/unit/memory_leak_spec.rb +1 -1
- data/spec/unit/namespaced_multiple_example_spec.rb +53 -0
- data/spec/unit/override_warning_spec.rb +43 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +1 -1
- data/spec/unit/persistence/active_record_persistence_spec.rb +1 -1
- data/spec/unit/persistence/mongoid_persistence_spec.rb +11 -0
- data/spec/unit/persistence/redis_persistence_spec.rb +77 -0
- data/spec/unit/readme_spec.rb +1 -2
- data/spec/unit/states_on_one_line_example_spec.rb +16 -0
- data/spec/unit/transition_spec.rb +60 -1
- metadata +22 -2
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'base'
|
2
|
-
|
3
1
|
module AASM
|
4
2
|
module Persistence
|
5
3
|
module MongoidPersistence
|
@@ -33,10 +31,23 @@ module AASM
|
|
33
31
|
def self.included(base)
|
34
32
|
base.send(:include, AASM::Persistence::Base)
|
35
33
|
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
|
34
|
+
base.extend AASM::Persistence::MongoidPersistence::ClassMethods
|
36
35
|
|
37
36
|
base.after_initialize :aasm_ensure_initial_state
|
38
37
|
end
|
39
38
|
|
39
|
+
module ClassMethods
|
40
|
+
def aasm_create_scope(state_machine_name, scope_name)
|
41
|
+
scope_options = lambda {
|
42
|
+
send(
|
43
|
+
:where,
|
44
|
+
{ aasm(state_machine_name).attribute_name.to_sym => scope_name.to_s }
|
45
|
+
)
|
46
|
+
}
|
47
|
+
send(:scope, scope_name, scope_options)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
40
51
|
module InstanceMethods
|
41
52
|
|
42
53
|
# Writes <tt>state</tt> to the state column and persists it to the database
|
@@ -95,8 +106,17 @@ module AASM
|
|
95
106
|
# foo.aasm_state # => nil
|
96
107
|
#
|
97
108
|
def aasm_ensure_initial_state
|
98
|
-
AASM::
|
99
|
-
|
109
|
+
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
|
110
|
+
attribute_name = self.class.aasm(state_machine_name).attribute_name.to_s
|
111
|
+
# Do not load initial state when object attributes are not loaded,
|
112
|
+
# mongoid has_many relationship does not load child object attributes when
|
113
|
+
# only ids are loaded, for example parent.child_ids will not load child object attributes.
|
114
|
+
# This feature is introduced in mongoid > 4.
|
115
|
+
if attribute_names.include?(attribute_name) && attributes[attribute_name].blank?
|
116
|
+
# attribute_missing? is defined in mongoid > 4
|
117
|
+
return if Mongoid::VERSION.to_f >= 4 && attribute_missing?(attribute_name)
|
118
|
+
send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s)
|
119
|
+
end
|
100
120
|
end
|
101
121
|
end
|
102
122
|
end # InstanceMethods
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module AASM
|
2
|
+
module Persistence
|
3
|
+
module RedisPersistence
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.send(:include, AASM::Persistence::Base)
|
7
|
+
base.send(:include, AASM::Persistence::RedisPersistence::InstanceMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
# Add the inital value to intiializer
|
12
|
+
#
|
13
|
+
# redis-objects removed the key from redis when set to nil
|
14
|
+
def initialize(*args)
|
15
|
+
super
|
16
|
+
state = send(self.class.aasm.attribute_name)
|
17
|
+
state.value = aasm.determine_state_name(self.class.aasm.initial_state)
|
18
|
+
end
|
19
|
+
# Returns the value of the aasm.attribute_name - called from <tt>aasm.current_state</tt>
|
20
|
+
#
|
21
|
+
# If it's a new record, and the aasm state column is blank it returns the initial state
|
22
|
+
#
|
23
|
+
# class Foo
|
24
|
+
# include Redis::Objects
|
25
|
+
# include AASM
|
26
|
+
# aasm :column => :status do
|
27
|
+
# state :opened
|
28
|
+
# state :closed
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# foo = Foo.new
|
33
|
+
# foo.current_state # => :opened
|
34
|
+
# foo.close
|
35
|
+
# foo.current_state # => :closed
|
36
|
+
#
|
37
|
+
# foo = Foo[1]
|
38
|
+
# foo.current_state # => :opened
|
39
|
+
# foo.aasm_state = nil
|
40
|
+
# foo.current_state # => nil
|
41
|
+
#
|
42
|
+
# NOTE: intended to be called from an event
|
43
|
+
#
|
44
|
+
# This allows for nil aasm states - be sure to add validation to your model
|
45
|
+
def aasm_read_state(name=:default)
|
46
|
+
state = send(self.class.aasm(name).attribute_name)
|
47
|
+
|
48
|
+
if state.value.nil?
|
49
|
+
nil
|
50
|
+
else
|
51
|
+
state.value.to_sym
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Ensures that if the aasm_state column is nil and the record is new
|
56
|
+
# that the initial state gets populated before validation on create
|
57
|
+
#
|
58
|
+
# foo = Foo.new
|
59
|
+
# foo.aasm_state # => nil
|
60
|
+
# foo.valid?
|
61
|
+
# foo.aasm_state # => "open" (where :open is the initial state)
|
62
|
+
#
|
63
|
+
#
|
64
|
+
# foo = Foo.find(:first)
|
65
|
+
# foo.aasm_state # => 1
|
66
|
+
# foo.aasm_state = nil
|
67
|
+
# foo.valid?
|
68
|
+
# foo.aasm_state # => nil
|
69
|
+
#
|
70
|
+
def aasm_ensure_initial_state
|
71
|
+
aasm.enter_initial_state if
|
72
|
+
send(self.class.aasm.attribute_name).to_s.strip.empty?
|
73
|
+
end
|
74
|
+
|
75
|
+
# Writes <tt>state</tt> to the state column and persists it to the database
|
76
|
+
#
|
77
|
+
# foo = Foo[1]
|
78
|
+
# foo.aasm.current_state # => :opened
|
79
|
+
# foo.close!
|
80
|
+
# foo.aasm.current_state # => :closed
|
81
|
+
# Foo[1].aasm.current_state # => :closed
|
82
|
+
#
|
83
|
+
# NOTE: intended to be called from an event
|
84
|
+
def aasm_write_state(state)
|
85
|
+
aasm_column = self.class.aasm.attribute_name
|
86
|
+
self.send("#{aasm_column}=", state)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
90
|
+
#
|
91
|
+
# foo = Foo[1]
|
92
|
+
# foo.aasm.current_state # => :opened
|
93
|
+
# foo.close
|
94
|
+
# foo.aasm.current_state # => :closed
|
95
|
+
# Foo[1].aasm.current_state # => :opened
|
96
|
+
# foo.save
|
97
|
+
# foo.aasm.current_state # => :closed
|
98
|
+
# Foo[1].aasm.current_state # => :closed
|
99
|
+
#
|
100
|
+
# NOTE: intended to be called from an event
|
101
|
+
def aasm_write_state_without_persistence(state)
|
102
|
+
send("#{self.class.aasm.attribute_name}=", state)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'base'
|
2
|
-
|
3
1
|
module AASM
|
4
2
|
module Persistence
|
5
3
|
module SequelPersistence
|
@@ -71,7 +69,7 @@ module AASM
|
|
71
69
|
# foo.aasm_state # => nil
|
72
70
|
#
|
73
71
|
def aasm_ensure_initial_state
|
74
|
-
AASM::
|
72
|
+
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
|
75
73
|
aasm(state_machine_name).enter_initial_state if
|
76
74
|
(new? || values.key?(self.class.aasm(state_machine_name).attribute_name)) &&
|
77
75
|
send(self.class.aasm(state_machine_name).attribute_name).to_s.strip.empty?
|
data/lib/aasm/state_machine.rb
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
module AASM
|
2
2
|
class StateMachine
|
3
|
-
|
4
|
-
# the following two methods provide the storage of all state machines
|
5
|
-
def self.[](klass)
|
6
|
-
(@machines ||= {})[klass.to_s]
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.[]=(klass, machine)
|
10
|
-
(@machines ||= {})[klass.to_s] = machine
|
11
|
-
end
|
3
|
+
# the following four methods provide the storage of all state machines
|
12
4
|
|
13
5
|
attr_accessor :states, :events, :initial_state, :config, :name, :global_callbacks
|
14
6
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module AASM
|
2
|
+
class StateMachineStore
|
3
|
+
class << self
|
4
|
+
def stores
|
5
|
+
@stores ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
# do not overwrite existing state machines, which could have been created by
|
9
|
+
# inheritance, see AASM::ClassMethods method inherited
|
10
|
+
def register(klass, overwrite = false, state_machine = nil)
|
11
|
+
raise "Cannot register #{klass}" unless klass.is_a?(Class)
|
12
|
+
|
13
|
+
case name = template = overwrite
|
14
|
+
when FalseClass then stores[klass.to_s] ||= new
|
15
|
+
when TrueClass then stores[klass.to_s] = new
|
16
|
+
when Class then stores[klass.to_s] = stores[template.to_s].clone
|
17
|
+
when Symbol then stores[klass.to_s].register(name, state_machine)
|
18
|
+
when String then stores[klass.to_s].register(name, state_machine)
|
19
|
+
else raise "Don't know what to do with #{overwrite}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias_method :[]=, :register
|
23
|
+
|
24
|
+
def fetch(klass, fallback = nil)
|
25
|
+
stores[klass.to_s] || fallback && begin
|
26
|
+
match = klass.ancestors.find do |ancestor|
|
27
|
+
ancestor.include? AASM and stores[ancestor.to_s]
|
28
|
+
end
|
29
|
+
|
30
|
+
stores[match.to_s]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
alias_method :[], :fetch
|
34
|
+
|
35
|
+
def unregister(klass)
|
36
|
+
stores.delete(klass.to_s)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@machines = {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def clone
|
45
|
+
StateMachineStore.new.tap do |store|
|
46
|
+
@machines.each_pair do |name, machine|
|
47
|
+
store.register(name, machine.clone)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def machine(name)
|
53
|
+
@machines[name.to_s]
|
54
|
+
end
|
55
|
+
alias_method :[], :machine
|
56
|
+
|
57
|
+
def machine_names
|
58
|
+
@machines.keys
|
59
|
+
end
|
60
|
+
alias_method :keys, :machine_names
|
61
|
+
|
62
|
+
def register(name, machine, force = false)
|
63
|
+
raise "Cannot use #{name.inspect} for machine name" unless name.is_a?(Symbol) or name.is_a?(String)
|
64
|
+
raise "Cannot use #{machine.inspect} as a machine" unless machine.is_a?(AASM::StateMachine)
|
65
|
+
|
66
|
+
if force
|
67
|
+
@machines[name.to_s] = machine
|
68
|
+
else
|
69
|
+
@machines[name.to_s] ||= machine
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/aasm/version.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
class
|
2
|
-
def
|
1
|
+
class Add<%= column_name.camelize %>To<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def change
|
3
3
|
add_column :<%= table_name %>, :<%= column_name %>, :string
|
4
4
|
end
|
5
|
-
|
6
|
-
def self.down
|
7
|
-
remove_column :<%= table_name %>, :<%= column_name %>
|
8
|
-
end
|
9
5
|
end
|
data/lib/motion-aasm.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
unless defined?(Motion::Project::App)
|
2
|
+
raise "This must be required from within a RubyMotion Rakefile"
|
3
|
+
end
|
4
|
+
|
5
|
+
file_dependencies = {
|
6
|
+
'aasm/aasm.rb' => ['aasm/persistence.rb'],
|
7
|
+
'aasm/persistence.rb' => ['aasm/persistence/plain_persistence.rb', 'aasm/persistence/core_data_query_persistence.rb'],
|
8
|
+
'aasm/persistence/base.rb' => ['aasm/base.rb'],
|
9
|
+
'aasm/persistence/core_data_query_persistence.rb' => ['aasm/persistence/base.rb']
|
10
|
+
}
|
11
|
+
|
12
|
+
exclude_files = [
|
13
|
+
'aasm/rspec.*',
|
14
|
+
'aasm/persistence/active_record_persistence.rb',
|
15
|
+
'aasm/persistence/dynamoid_persistence.rb',
|
16
|
+
'aasm/persistence/mongo_mapper_persistence.rb',
|
17
|
+
'aasm/persistence/mongoid_persistence.rb',
|
18
|
+
'aasm/persistence/sequel_persistence.rb',
|
19
|
+
'aasm/persistence/redis_persistence.rb'
|
20
|
+
]
|
21
|
+
|
22
|
+
Motion::Project::App.setup do |app|
|
23
|
+
parent = File.expand_path File.dirname(__FILE__)
|
24
|
+
|
25
|
+
app.files.unshift Dir.glob(File.join(parent, "aasm/**/*.rb")).reject { |file| exclude_files.any? { |exclude| file.match(exclude) } }
|
26
|
+
|
27
|
+
app.files_dependencies file_dependencies.inject({}, &->(file_dependencies, (file, *dependencies)) do
|
28
|
+
file = File.join(parent, file)
|
29
|
+
dependencies = dependencies.flatten(1).map do |dependency|
|
30
|
+
File.join(parent, dependency)
|
31
|
+
end
|
32
|
+
|
33
|
+
file_dependencies.merge({ file => dependencies })
|
34
|
+
end)
|
35
|
+
end
|
@@ -39,8 +39,15 @@ module Callbacks
|
|
39
39
|
:exit => :exit_closed,
|
40
40
|
:after_exit => :after_exit_closed
|
41
41
|
|
42
|
-
event :close,
|
43
|
-
|
42
|
+
event :close,
|
43
|
+
:before => :before_event,
|
44
|
+
:after => :after_event,
|
45
|
+
:guard => :event_guard,
|
46
|
+
:ensure => :ensure_event do
|
47
|
+
transitions :to => :closed, :from => [:open],
|
48
|
+
:guard => :transition_guard,
|
49
|
+
:after => :after_transition,
|
50
|
+
:success => :success_transition
|
44
51
|
end
|
45
52
|
|
46
53
|
event :open, :before => :before_event, :after => :after_event do
|
@@ -79,6 +86,9 @@ module Callbacks
|
|
79
86
|
def after_event; log('after_event'); end
|
80
87
|
def after_all_events; log('after_all_events'); end
|
81
88
|
|
89
|
+
def after_transition; log('after_transition'); end
|
90
|
+
def success_transition; log('transition_success'); end
|
91
|
+
|
82
92
|
def ensure_event; log('ensure'); end
|
83
93
|
def ensure_on_all_events; log('ensure'); end
|
84
94
|
end
|
@@ -26,7 +26,7 @@ module Callbacks
|
|
26
26
|
:after_exit => :after_exit_closed
|
27
27
|
|
28
28
|
event :close, :before => :before, :after => :after, :guard => :event_guard do
|
29
|
-
transitions :to => :closed, :from => [:open], :after => :transitioning do
|
29
|
+
transitions :to => :closed, :from => [:open], :after => :transitioning, :success => :success_transition do
|
30
30
|
guard do
|
31
31
|
transition_guard
|
32
32
|
end
|
@@ -59,6 +59,7 @@ module Callbacks
|
|
59
59
|
def event_guard; log('event_guard'); !@fail_event_guard; end
|
60
60
|
def transition_guard; log('transition_guard'); !@fail_transition_guard; end
|
61
61
|
def transitioning; log('transitioning'); end
|
62
|
+
def success_transition; log('success transition'); end
|
62
63
|
|
63
64
|
def before; log('before'); end
|
64
65
|
def after; log('after'); end
|
@@ -28,7 +28,7 @@ module Callbacks
|
|
28
28
|
state :failed
|
29
29
|
|
30
30
|
event :close, :before => :before, :after => :after, :guard => :event_guard do
|
31
|
-
transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :transitioning
|
31
|
+
transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :transitioning, :success => :success_transition
|
32
32
|
transitions :to => :failed, :from => [:open]
|
33
33
|
end
|
34
34
|
|
@@ -58,6 +58,7 @@ module Callbacks
|
|
58
58
|
def event_guard; log('event_guard'); !@fail_event_guard; end
|
59
59
|
def transition_guard; log('transition_guard'); !@fail_transition_guard; end
|
60
60
|
def transitioning; log('transitioning'); end
|
61
|
+
def success_transition; log('transition success'); end
|
61
62
|
|
62
63
|
def before; log('before'); end
|
63
64
|
def after; log('after'); end
|
@@ -29,7 +29,7 @@ module Callbacks
|
|
29
29
|
:after_exit => :after_exit_closed
|
30
30
|
|
31
31
|
event :close, :before => :before, :after => :after do
|
32
|
-
transitions :to => :closed, :from => [:open], :after => :transition_proc
|
32
|
+
transitions :to => :closed, :from => [:open], :after => :transition_proc, :success => :transition_success_proc
|
33
33
|
end
|
34
34
|
|
35
35
|
event :open, :before => :before, :after => :after do
|
@@ -57,5 +57,6 @@ module Callbacks
|
|
57
57
|
def before(arg1, *args); log("before(#{arg1.inspect},#{args.map(&:inspect).join(',')})"); end
|
58
58
|
def transition_proc(arg1, arg2); log("transition_proc(#{arg1.inspect},#{arg2.inspect})"); end
|
59
59
|
def after(*args); log("after(#{args.map(&:inspect).join(',')})"); end
|
60
|
+
def transition_success_proc(*args); log("transition_success(#{args.map(&:inspect).join(',')})"); end
|
60
61
|
end
|
61
62
|
end
|
@@ -9,8 +9,8 @@ module Callbacks
|
|
9
9
|
state :out_to_lunch
|
10
10
|
|
11
11
|
event :close, :before => :before_method, :after => :after_method do
|
12
|
-
transitions :to => :closed, :from => [:open], :after => :transition_method
|
13
|
-
transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2
|
12
|
+
transitions :to => :closed, :from => [:open], :after => :transition_method, :success => :success_method
|
13
|
+
transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2, :success => :success_method2
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -22,5 +22,9 @@ module Callbacks
|
|
22
22
|
|
23
23
|
def transition_method2(arg); end
|
24
24
|
|
25
|
+
def success_method(arg); end
|
26
|
+
|
27
|
+
def success_method2(arg); end
|
28
|
+
|
25
29
|
end
|
26
30
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Parent
|
2
|
+
include Mongoid::Document
|
3
|
+
include AASM
|
4
|
+
|
5
|
+
field :status, :type => String
|
6
|
+
has_many :childs
|
7
|
+
|
8
|
+
aasm column: :status do
|
9
|
+
state :unknown_scope
|
10
|
+
state :new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Child
|
15
|
+
include Mongoid::Document
|
16
|
+
include AASM
|
17
|
+
field :parent_id
|
18
|
+
|
19
|
+
field :status, :type => String
|
20
|
+
belongs_to :parent
|
21
|
+
|
22
|
+
aasm column: :status do
|
23
|
+
state :unknown_scope
|
24
|
+
state :new
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class NamespacedMultipleExample
|
2
|
+
include AASM
|
3
|
+
aasm(:status) do
|
4
|
+
state :unapproved, :initial => true
|
5
|
+
state :approved
|
6
|
+
|
7
|
+
event :approve do
|
8
|
+
transitions :from => :unapproved, :to => :approved
|
9
|
+
end
|
10
|
+
|
11
|
+
event :unapprove do
|
12
|
+
transitions :from => :approved, :to => :unapproved
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
aasm(:review_status, namespace: :review) do
|
17
|
+
state :unapproved, :initial => true
|
18
|
+
state :approved
|
19
|
+
|
20
|
+
event :approve_review do
|
21
|
+
transitions :from => :unapproved, :to => :approved
|
22
|
+
end
|
23
|
+
|
24
|
+
event :unapprove_review do
|
25
|
+
transitions :from => :approved, :to => :unapproved
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|