86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'lib/status_workflow.rb', line 86
def status_workflow(workflows)
if workflows.first.last.is_a?(Array)
workflows = { nil => workflows }
end
workflows.each do |prefix, transitions|
if prefix
prefix_ = "#{prefix}_"
define_method "#{prefix_}status_transition!" do |*args, &blk|
status_transition!(*(args+[prefix]), &blk)
end
end
transitions.inject({}) do |memo, (from_status, to_statuses)|
to_statuses.each do |to_status|
to_status = to_status.to_sym
memo[to_status] ||= Set.new
memo[to_status] << from_status.to_sym
end
memo
end.tap do |to_from|
to_from[:error] = Set.new
to_from.each do |to_status, from_statuses|
to_from[:error].merge from_statuses
end
end.each do |to_status, from_statuses|
define_method "#{prefix_}enter_#{to_status}!" do
send "#{prefix_}status_transition!", nil, to_status
end
define_method "#{prefix_}can_enter_#{to_status}?" do |raise_error = false|
reload
status = read_attribute "#{prefix_}status"
memo = from_statuses.include? status&.to_sym
if raise_error and not memo
raise InvalidTransition, "can't enter #{to_status} from #{status}, expected #{from_statuses.to_a.join('/')}"
end
memo
end
define_method "#{prefix_}enter_#{to_status}_if_possible" do
begin; send("#{prefix_}enter_#{to_status}!"); rescue InvalidTransition; false; end
end
end
end
end
|