Skip to content
Dave Strus edited this page Jul 18, 2015 · 2 revisions

Sign Up Page

To let users log in, we'll first need some kind of "Sign up" form, so let's add a route and controller for new user registrations.

Let's add RESTful routes for users, but limit them to the create action for the time being. We'll use a separate, named route for users#new.

config/routes.rb

resources :users, only: :create
get 'sign_up' => 'users#new'

Add a link to this new route to the header in our layout:

app/views/layouts/application.html.erb

<header>
  <div class="well">
    Nevernote
    <%= link_to 'Sign Up', sign_up_path %>
  </div>
</header>

In HAML:

%header
  .well
    Nevernote
    = link_to 'Sign Up', sign_up_path

Before we can view the page, we'll need a controller and a view. Let's pause for a moment before jumping into our controller.

Locales

Rather than writing the text for our flash messages inline, we'll use a locale file. Locale files define text to be used throughout the app, in support of internationalization. Rather than hardcoding the text within the app itself, all such text can be defined in language-specific YAML files. Let's put the text for registration-related flash messages in our English locale file.

config/locales/en.yml

en:
  hello: "Hello world"
  user:
    flash:
      create:
        success: "Thanks for signing up!"
        failure: "There was a problem with your registration."

UsersController

Let's create the controller with the appropriate actions, using locale-specific flash messages.

app/controllers/users_controller.rb

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new user_params
    if @user.save
      session[:user_id] = @user.id
      redirect_to root_url, notice: t('user.flash.create.success')
    else
      flash.now[:alert] = t('user.flash.create.failure')
      render :new
    end
  end

  private

  def user_params
    params.require(:user).permit(:username, :name, :password, :password_confirmation)
  end
end

Create the view for the sign up page:

app/views/users/new.html.erb

<h3>Sign Up for Nevernote</h3>
<%= form_for @user do |f| %>
  <p>
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :username %><br>
    <%= f.text_field :username %>
  </p>
  <p>
    <%= f.label :password %><br>
    <%= f.password_field :password %>
  </p>
  <%= f.submit 'Sign Up', class: 'btn btn-default' %>
<% end %>

HAML:

%h3 Sign Up for Nevernote
= form_for @user do |f|
  %p
    = f.label :name
    %br/
    = f.text_field :name
  %p
    = f.label :username
    %br/
    = f.text_field :username
  %p
    = f.label :password
    %br/
    = f.password_field :password
  = f.submit 'Sign Up', class: 'btn btn-default'

We don't need the sidebar on the sign up page. In fact, let's use an entirely different layout.

app/views/layouts/landing.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>Nevernote</title>
  <%= stylesheet_link_tag    'application', media: 'all' %>
  <%= javascript_include_tag 'application' %>
  <%= csrf_meta_tags %>
</head>
<body id="welcome">

<div class="container wrap">
  <div class="row">
    <div class="col-xs-12">
      <header>
        <div class="well">
          Nevernote
        </div>
      </header>
    </div>
  </header>
  <div class="container">
    <div class="row">
      <div class="col-xs-12">
        <main>
          <!-- BEGIN main content -->
          <%= flash_messages(flash) %>
          <%= yield %>
        </main>
      </div>
    </div>
  </div>
</div>

</body>
</html>

HAML:

!!!
%html
  %head
    %title Nevernote
    = stylesheet_link_tag    'application', media: 'all'
    = javascript_include_tag 'application'
    = csrf_meta_tags
  %body#welcome
    .container.wrap
      .row
        .col-xs-12
          %header
            .well
              Nevernote
        .container
          .row
            .col-xs-12
              %main
                = flash_messages(flash)
                = yield

To use this layout for user-related actions, add layout 'landing' to UsersController.

app/controllers/users_controller

class UsersController < ApplicationController
  layout 'landing'

Before we try signing up, let's edit the User model to require username and enforce its uniqueness.

app/models/user.rb

validates :username, presence: true, uniqueness: true

Visit /sign_up and try registering a new user. If it works, commit!

$ git add .
$ git commit -m "Implement user sign up."