Ever write this?
before_filter :authorize
protected
def authorize
unless logged_in?
session[:return_to] = request.request_uri
redirect_to login_url and return false
end
end
You want your before_filter
to authorize the current_user
unless they are
logged in. So why not say it like you mean it?
before_filter :authorize, :unless => logged_in?
protected
def authorize
session[:return_to] = request.request_uri
redirect_to login_url and return false
end
This is more expressive. The conditional logic is no longer hidden in the method.
The authorize method now has a single responsibility: to authorize. The
before_filter
, responsible for performing some action before your controller
action is called, is now smarter about when it is supposed to run.
Introducing When
The When Rails plugin adds :if
and
:unless
modifiers to before_filters
, most ActiveRecord callbacks, and
validations.
Use it to improve your controllers:
before_filter :deny_access, :unless => :admin?
protected
def deny_access
flash[:failure] = "You do not have access to that page."
redirect_to home_url
end
def admin?
logged_in? and current_user.admin?
end
Improve your models, too:
before_create :encrypt_password,
:unless => lambda {|user| user.password_confirmation.blank?}
after_save :send_alerts, :if => :alerts?
validate_on_create :add_unsupported_type_error,
:unless => lambda {|document| SUPPORTED_FILE_TYPES.include? document.file_type}
Coding Without Ifs
Jared makes a strong argument that this is actually removing conditional logic from your program. I tend to agree.
It reminds me of defining constants in your environments so you don’t write
conditional logic that checks the RAILS_ENV
. That kind of control flow belongs
in the framework.
Whether this is removing conditional logic is moot, though. It just feels right, and isn’t that why we write Ruby?
Update: after releasing this, we found out this is already in Rails trunk.
Awesome! It’s a great feature and should be in the framework. So, if you’re not
running on Edge, use the when plugin to get this feature now. Then, remove
it when you upgrade to the next version of Rails, when you’ll get :if
s and
:unless
es for free. Happy coding!