aasm 4.9.0 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|