def perform(transitions, options = {})
attributes = transitions.map {|transition| transition.attribute}.uniq
raise ArgumentError, 'Cannot perform multiple transitions in parallel for the same state machine attribute' if attributes.length != transitions.length
success = false
if transitions.all? {|transition| transition.before}
transitions.each {|transition| transition.persist}
begin
results = {}
success =
if block_given?
result = yield
transitions.each {|transition| results[transition.action] = result}
!!result
elsif options[:action] == false
true
else
object = transitions.first.object
transitions.all? do |transition|
action = transition.action
action && !results.include?(action) ? results[action] = object.send(action) : true
end
end
rescue Exception
transitions.each {|transition| transition.rollback}
raise
end
transitions.each {|transition| transition.after(results[transition.action], success)} unless options[:after] == false && success
transitions.each {|transition| transition.rollback} unless success
end
success
end