---
title: Sign Up, Sign In, Sign Out
teaser:
tags: web,rails,clearance,language
author: Dan Croak
published_on: 2009-07-08
---

What is your [Ubiquitous Language][language] for authentication?

[language]: http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215

Common language includes "logging in", "registering", "joining up", "creating an
account", "signing up", and "signing out."

Do you interchange these words in your UI? How about in your application code?
Tests? Does your whole team use the same language across all layers of the
software?

When writing a library like [Clearance](http://github.com/thoughtbot/clearance),
I feel the authors should take a stand on language to alleviate the mental
burden on designers, developers, and business analysts involved in the project.

The decision is basically arbitrary. No one set of terms is better than the
other. What's important is to take the opportunity to standardize all the places
this shows up in code.

So we picked "sign up", "sign in", and "sign out", a lingual trinity of
authentication.

We liked the symmetry. We liked that there was less of a chance of writing "log
in" (sounds like a verb) or `log_in` in certain places and "login" (sounds like
a noun) other places.

About a half a year later and we still feel good about the effect.

## Tests

```ruby
context 'when signed out' do
  context 'on get to new' do
    setup do
      get :new
    end

    should_deny_access
  end
end

context 'when signed in' do
  setup do
    sign_in
  end

  context 'on get to new' do
    setup do
      get :new
    end

    ...
  end
end

context 'when signed in as an admin' do
  setup do
    sign_in_as create(:admin)
  end

  context 'on delete to destroy' do
    setup do
      delete :destroy
    end

    ...
  end
end
```

## Application code

```ruby
class UsersController < Clearance::UsersController
  def create
    ...
    sign_in(@user)
  end
end

class ParticipationsController < ApplicationController
  private

  def ensure_signed_in
    unless signed_in?
      store_location
      flash[:failure] = 'Please sign in to participate in this deal.'
      redirect_to sign_in_path
    end
  end
end

module NavigationHelper
  def authentication_links
    if signed_in?
      signed_in_links
    else
      signed_out_links
    end
  end

  def signed_out_links
    [
      link_to('Sign up', sign_up_path),
      link_to('Sign in', sign_in_path)
    ]
  end

  def signed_in_links
    [
      link_to('My Account', edit_user_path(current_user)),
      link_to('Sign out', sign_out_path)
    ]
  end
end
```

## UI

For something as common as authentication, familiarity for users breeds comfort.
So what do the others do?

Basecamp is a little inconsistent, mixing sign in with login:

![basecamp openid form](http://images.thoughtbot.com/ui/2009-7-8-basecamp_openid.png)
![basecamp username form](http://images.thoughtbot.com/ui/2009-7-8-basecamp_username.png)

Apple is pretty as usual:

![apple sign in](http://images.thoughtbot.com/ui/2009-7-8-itunes_2.png)

Google is perfectly consistent. Youtube and Gmail:

![Google sign in](http://images.thoughtbot.com/ui/2009-7-8-youtube_sign_up_in.png)
![Google sign in](http://images.thoughtbot.com/ui/2009-7-8-youtube.png)
![Google sign in](http://images.thoughtbot.com/ui/2009-7-8-gmail.png)

Sweet, sweet consistency.
