Ruby on Rails

Rails 8 User registration

This post describes how to create a User registration functionality for a Rails 8 application that uses the default Rails 8 authentication framework.

In the routes file, add routes for the registration: new and create. Note: the route is singular.


# config/routes.rb

resource :registration, only: [:new, :create]

Add a new RegistrationsController in app/controllers/registrations_controller.rb with new and create actions.

# app/controllers/registrations_controller.rb

class RegistrationsController < ApplicationController
  allow_unauthenticated_access only: [ :new, :create ]

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      start_new_session_for @user
      redirect_to root_path, notice: "Successfully signed up!"
    else
      flash.now[:alert] = "Something went wrong."
      render :new, status: :unprocessable_entity
    end
  end

  private

  def user_params
    params.expect(user: [:first_name, :last_name, :email_address, :password, :password_confirmation])
  end
end

Create a new view in registrations/new.html.erb with this content:

<%= form_with model: @user, url: registration_url do |form| %>

  <%= render "shared/errors", object: @user %>

  <div>
    <%= form.label :first_name %>
    <%= form.text_field :first_name,
      required: true,
      autofocus: true,
      placeholder: "your first name" %>
  </div>

  <div>
    <%= form.label :last_name%>
    <%= form.text_field :last_name,
      required: true,
      placeholder: "your last name" %>
  </div>

  <div>
    <%= form.label :email_address%>
    <%= form.email_field :email_address,
      required: true,
      placeholder: "your email address" %>
  </div>

  <div>
    <%= form.label :password, "New password" %>
    <%= form.password_field :password,
      required: true,
      placeholder: "your new password",
      maxlength: 72 %>
  </div>

  <div>
    <%= form.label :password_confirmation %>
    <%= form.password_field :password_confirmation,
      required: true,
      placeholder: "your password again",
      maxlength: 72 %>
  </div>

    <%= form.submit "Sign up" %>
<% end %>

User Model

class User < ApplicationRecord
  has_secure_password
  has_many :sessions, dependent: :destroy

  validates :first_name, presence: true
  validates :last_name, presence: true
  validates :email_address, presence: true, uniqueness: true
  validates :password, presence: true
  validates :password_confirmation, presence: true
  validates_confirmation_of :password

  normalizes :email_address, with: ->(e) { e.strip.downcase }
end

Errors partial app/views/shared/_errors.html.erb


<% if object.errors.any? %>
  <section class="bg-orange-200 p-8 my-8 mx-auto">
    <h2>
      Your form could not be saved.
    </h2>
    <h3>
      Please correct the following
      <%= pluralize(object.errors.size, "error") %>:
    </h3>
    <ul>
      <% object.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </section>
<% end %>

Styling the .field_with_errors class in the main application.css file:

/* app/assets/stylesheets/application.css */

div.field_with_errors > label {
  color: red;
}

div.field_with_errors > :is(input, textarea, select) {
  border: 2px solid red;
  margin-bottom: 1rem;
}
← All posts Recent blog posts →