---
title: When, a Rails plugin
teaser: Introducing a confusingly-named plugin, `when`.
tags: news,web,rails
author: Dan Croak
published_on: 2008-02-15
---

Ever write this?

```ruby
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?

```ruby
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](https://github.com/thoughtbot/when) Rails plugin adds `:if` and
`:unless` modifiers to `before_filters`, most ActiveRecord callbacks, and
validations.

Use it to improve your controllers:

```ruby
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:

```ruby
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](https://thoughtbot.com/blog/designing-without-ifs)
[logic](https://thoughtbot.com/blog/coding-without-ifs) 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!
