A filter can take one of three forms: method reference (symbol), external class, or block.
The first is by far the most common and works by referencing a protected method some-
where in the inheritance hierarchy of the controller. In the bank example in my previous post,
both BankController and VaultController use this form.
- Filter Classes
Using an external class makes for more easily reused generic filters, such as output
compression. External filter classes are implemented by having a static filter method on
any class and then passing this class to the filter method, as in code below. The name of
the class method should match the type of filter desired (e.g., before, after, around).
class OutputCompressionFilter
def self.after(controller)
controller.response.body = compress(controller.response.body)
end
endclass NewspaperController < ActionController::Base
after_filter OutputCompressionFilter
end
The method of the Filter class is passed the controller instance it is filtering. It gets
full access to the controller and can manipulate it as it sees fit. The fact that it gets an
instance of the controller to play with also makes it seem like feature envy, and frankly,
I haven’t had much use for this technique.
- Inline Method
The inline method (using a block parameter to the filter method) can be used to quickly
do something small that doesn’t require a lot of explanation or just as a quick test.
class WeblogController < ActionController::Base
before_filter do
redirect_to new_user_session_path unless authenticated?
end
end
The block is executed in the context of the controller instance, using instance_eval.
This means that the block has access to both the request and response objects complete
with convenience methods for params, session, template, and assigns.