-
Notifications
You must be signed in to change notification settings - Fork 629
/
transition.rb
76 lines (63 loc) · 2.44 KB
/
transition.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module AASM::Core
class Transition
include DslHelper
attr_reader :from, :to, :event, :opts
alias_method :options, :opts
def initialize(event, opts, &block)
add_options_from_dsl(opts, [:on_transition, :guard, :after], &block) if block
@event = event
@from = opts[:from]
@to = opts[:to]
@guards = Array(opts[:guards]) + Array(opts[:guard]) + Array(opts[:if])
@unless = Array(opts[:unless]) #TODO: This could use a better name
if opts[:on_transition]
warn '[DEPRECATION] :on_transition is deprecated, use :after instead'
opts[:after] = Array(opts[:after]) + Array(opts[:on_transition])
end
@after = Array(opts[:after])
@after = @after[0] if @after.size == 1
@opts = opts
end
def allowed?(obj, *args)
invoke_callbacks_compatible_with_guard(@guards, obj, args, :guard => true) &&
invoke_callbacks_compatible_with_guard(@unless, obj, args, :unless => true)
end
def execute(obj, *args)
invoke_callbacks_compatible_with_guard(event.state_machine.global_callbacks[:after_all_transitions], obj, args)
invoke_callbacks_compatible_with_guard(@after, obj, args)
end
def ==(obj)
@from == obj.from && @to == obj.to
end
def from?(value)
@from == value
end
private
def invoke_callbacks_compatible_with_guard(code, record, args, options={})
if record.respond_to?(:aasm)
record.aasm(event.state_machine.name).from_state = @from if record.aasm(event.state_machine.name).respond_to?(:from_state=)
record.aasm(event.state_machine.name).to_state = @to if record.aasm(event.state_machine.name).respond_to?(:to_state=)
end
case code
when Symbol, String
arity = record.send(:method, code.to_sym).arity
arity == 0 ? record.send(code) : record.send(code, *args)
when Proc
code.arity == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code)
when Array
if options[:guard]
# invoke guard callbacks
code.all? {|a| invoke_callbacks_compatible_with_guard(a, record, args)}
elsif options[:unless]
# invoke unless callbacks
code.all? {|a| !invoke_callbacks_compatible_with_guard(a, record, args)}
else
# invoke after callbacks
code.map {|a| invoke_callbacks_compatible_with_guard(a, record, args)}
end
else
true
end
end
end
end # AASM