Using Rails’ before_filter
is a great way to keep your controller actions
clean by moving logic about authentication, authorization, or state of the
resource out of the main method, right?
The common wisdom
Here’s a typical usage of before_filter
:
class Admin::ArticlesController < ApplicationController
before_filter :deny_access, :unless => :draft_and_admin?
def show
@article = Article.find(params[:id])
end
protected
def draft_and_admin?
Article.find(params[:id]).draft? && current_user.admin?
end
end
Awesome. We deny the user access to the show action if the article is a draft and they are not an admin. The show action looks standard. When we look at the top of the file, we see a nice one-liner encapsulating concerns of authorization.
The hip wisdom
If we were using a RESTful controller abstraction such as inherited_resources, our code might look like this:
class Admin::ArticlesController < InheritedResources::Base
before_filter :deny_access, :unless => :draft_and_admin?
actions :show
protected
def draft_and_admin?
Article.find(params[:id]).draft? && current_user.admin?
end
end
The shortest of our three options, this approach requires more knowledge of the libraries in use.
The old-school wisdom
What if it looked like this?
class Admin::ArticlesController < ApplicationController
def show
if draft_and_admin?
@article = Article.find(params[:id])
render
else
deny_access
end
end
protected
def draft_and_admin?
Article.find(params[:id]).draft? && current_user.admin?
end
end
This is not standard Rails!
Yet all the logic is inline inside the action. It reads sequentially. It even
has an explicit render
in there, thumbing its nose at the Rails way!
The core responsibility of the action (fetching the Article of a given id) is more muddled here but the path of the code is clear to any Rubyist. No special knowledge required.
The Questions
What advantage does before_filter
provide that Ruby does not? Does the
before_filter
layer of indirection make the code easier or harder to read? Do
RESTful controller abstractions influence our preference?