-
Notifications
You must be signed in to change notification settings - Fork 0
09 User Sign Up
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.
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."
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."