geekq/workflow — pull request #58 by svoop (2012-12-15 09:59:39+00:00)
Title: Limit private callback lookup.

Support for private callbacks introduced in commit 71937c04ef is a good thing, however, the way private callbacks are looked up caused a nasty issue in one of my models dealing with credit cards:

class CreditcardPayment < ActiveRecord::Base
workflow do
state :pending do
(...)
event :fail, transitions_to: :failed
end
state :failed
end
end

Now try to transition with `fail!` and - kaboom - runtime error. The problem is the lookup in the workflow gem:

def has_callback?(action)
self.respond_to?(action) or self.class.private_method_defined?(action)
end

Eventhough no private event handler `fail` is defined in the model, `private_method_defined?` still returns `true` as it does for **any** object due to `Kernel#fail`.

The problem is quite nasty and since "fail" appears to be a rather common transition in workflows, using another event name is not the best solution. But there's an easy way to limit the method lookup:

def has_callback?(action)
self.respond_to?(action) or self.private_methods(false).include?(action)
end

Which is exactly what this pull request contains :-)