---
title: Relax Dont Do it When You Want to Go to It
teaser: Authorization code for Rails.
tags: web,rails
author: Jared Carroll
published_on: 2007-01-19
---

In apps I like to follow a pattern:  each model has their own controller that
handles the <abbr title="Create Read Update Delete">CRUD</abbr> actions for that
model.  For example, the `Blog` model has the `BlogsController` and the `User`
model has the `UsersController`.  This is nice because if I need to know how to
<abbr title="Create Read Update Delete">CRUD</abbr> a particular model I know
right where to look, in its corresponding controller.

Ok let's go with this some more.

Say I have an `Account` and it needs to be authorized by someone before you can
access it.  Let's model it:

```ruby
class Account < ActiveRecord::Base
  has_one :authorization
end
class Authorization < ActiveRecord::Base
  belongs_to :account
  belongs_to :user
end
class User < ActiveRecord::Base
end
```

We could have modeled this as a boolean attribute `authorized` on the `Account`
class but we also want to track what time an account was authorized (we can let
Rails do this for us by using `created_on`) and which `User` authorized it.  I
like this because I think boolean flags feel dirty and can quickly get out of
hand.  I'd rather model states as objects, making my domain model richer.  The
phrase Oh we'll just set a flag, is definitely one of my most hated in software
development.

Anyway here's our tables:

    accounts (id, number, balance)
    authorizations (id, account_id, user_id, created_on)

Now following the controller per model pattern we'd have :

* `AccountsController`
* `AuthorizationsController`
* `UsersController`

Now I don't like to consider performance but by creating an `Authorization`
model we now require a join from `accounts` to `authorizations` just to
determine if an `Account` has been authorized as opposed to just reading an
attribute in the `Account` object.

Maybe we went too far but what if didn't then, we'd have something like:

```ruby
class AccountsController < ApplicationController
  def authorize
  end
  # all our CRUD actions
end
```

What is #authorize? That is not Creating, Reading, Updating or Deleting an
`Account` object.  I guess you could say "yeah it's Updating just 1 attribute
of an `Account`".  No, I don't like it; I want my #edit action to edit the
whole object.  Like I said before, I want my controllers to handle *only* the
<abbr title="Create Read Update Delete">CRUD</abbr> actions for a particular
model.  It turned out we were missing a concept, an `Authorization`.
Replacing that boolean with a model kept our <abbr title="Create Read Update
Delete">CRUD</abbr> only pattern alive.  Authorizing an account became creating
an `Authorization`:

```ruby
class AuthorizationsController < ApplicationController
  def new
  end
  def create
  end
end
```

What is #authorize? That is not Creating, Reading, Updating or Deleting an
`Account` object.  I guess you could say yeah it's Updating just 1 attribute of
an `Account`.  No, I don't like it; I want my #edit action to edit the whole
object.  Like I said before, I want my controllers to handle **only** the <abbr
title="Create Read Update Delete">CRUD</abbr> actions for a particular model.
It turned out we were missing a concept, an `Authorization`.  Replacing that
boolean with a model kept our <abbr title="Create Read Update
Delete">CRUD</abbr> only pattern alive.  Authorizing an account became creating
an `Authorization`:

```ruby
class AuthorizationsController < ApplicationController

  def new
    @account = Account.find params[:id]
  end

  def create
    @account = Account.find params[:id]
     if @account.update_attributes params[:account]
        redirect_to :controller => 'accounts', :action => :show, :id => @account.id
     else
        render :action => :new
     end
  end

end
```

What if we relaxed the pattern a bit.  Say, no longer can controllers only deal
with their corresponding models.

For example, the `BlogsController` can now work with any model not just `Blog`s.

However, controllers can still **only** have <abbr title="Create Read Update
Delete">CRUD</abbr> actions.

Let's also eliminate the `Authorization` model and just let `Account` have a
boolean attribute named `authorized`, a integer called `authorizer_id` and a
datetime called `authorized_on`.

Alright here we go.

```ruby
class SessionsController < ApplicationController

  def new
  end

  def create
  end

end
```

The `#new` action would display something along the lines of a form saying 'Do
you want to authorize Account #A-1'?  The form would then post to `#create`,
using hidden fields containing a boolean value of `true` for the `Account`
object's `authorized` attribute, the current time for its `authorized_on`
attribute, and the id of the currently logged in user for its `authorizer_id`
attribute.  The `#update_attributes` call in `#create` would update the
`Account` objects `authorized`, `authorizer_id` and `authorized_on` attributes,
thus authorizing the `Account`.

Here's another common one.

When dealing with sessions don't create a `LoginController` with say `#index`
and `#login` actions, create a `SessionsController` who is `#new` and `#create`
actions authenticate the given credentials.

```ruby
class UsersController < ApplicationController

  def send_password_reminder
  end

end
```

Another one; typically apps that require a login end up with a 'forgot password'
feature where a user gets emailed a link that allows them to reset their
password.  Usually this ends us in the `UsersController` like this:

```ruby
class RemindersController < ApplicationController

  def create
  end

end
```

What is `#send_password_reminder?` It's trash.  And its certainly not <abbr
title="Create Read Update Delete">CRUD</abbr>.  How about we do this:

```ruby
class UsersController < ApplicationController

  def edit_password
  end

  def update_password
  end

  def edit
  end

  def update
  end

end
```

Ahh that's better.  Back to our <abbr title="Create Read Update
Delete">CRUD</abbr>.  Now there's no `Reminder` model but remember we relaxed
the pattern by allowing controllers to deal with any model.  And if someone says
Hey I don't think the password reminder form's working right, we know right
where to look, in the `RemindersController` because we're creating a reminder;
we don't have to wade through the `UsersController` looking for some weird named
action like `#send_password_reminder`.

One more.

Sometimes in apps, users like to be able to edit their profile, which would
include things like first name, last name, address, etc.  But it would not
include password.  They like to be able to edit/change their password
separately.  Typically this ends up like this:

```ruby
class PasswordsController < ApplicationController

  def new
  end

  def create
  end

end
```

Now we have an `#edit_password` and `#update_password` in addition to our normal
`#edit` and `#update` actions which deal with editing non-password user info.
Once again, trash.  How about this:

```ruby
class PasswordsController < ApplicationController

  def new
  end

  def create
  end

end
```

There we go.  We're creating a new password for a given `User`.  Back to our
<abbr title="Create Read Update Delete">CRUD</abbr>.

You see with this relaxed version of the controller per model pattern we still
get to keep our nice <abbr title="Create Read Update Delete">CRUD</abbr>
actions, so every controller looks exactly the same i.e. they have all the same
named actions.  And we don't have to create a whole bunch of models, which
results in more tables, more joins, etc.  This style is in line with the new
<abbr title="Representational State Transfer">REST</abbr> stuff in Rails 1.2.

<abbr title="Create Read Update Delete">CRUD</abbr> 4 Life.
