I just spent a few hours tracking down a bug in Rails 1.1, so I thought
I’d post the issue and a workaround just in case anyone else hits it.
I designed a security enhancement so that controller methods can be
protected by preceding them with a role. The standard Ruby
method_added() callback is used to detect when controller methods are
added, and then I manipulate the controller’s before_filter chain
appropriately. My code worked fine in Rails 1.0, and then stopped
working in Rails 1.1.
I eventually tracked down the bug to the new implementation of
ActionController::Filters::before_filters and include_actions, which
cache their results the first time they are called. This caching
approach works fine as long as before_filters and include_actions are
only called after all the filters have been registered, but I was
using them during the registration process to figure out how to
manipulate the filter chain. Since Rails 1.1 caches their value the
first time they’re called, their return value is out of date if more
filters are added.
A workaround is to bypass the cache and use
read_inheritable_attribute(“before_filters”) instead of before_filters.
Similarly, use read_inheritable_attribute(“included_actions”) instead of
included_actions. This is bad because now my code is tied to an
implementation detail which would normally be hidden.
Incidentally, the same bug also occurs in after_filters and
excluded_actions.
Cheers,
Graham