Rails 8 Authentication generator: user registration
Previously I wrote about the new Rails Sessions generator.
Currently the generator allows email-password log in for existing users. It does not tackle registrations.
Let’s add registrations!
First, add a new registration
route:
# config/routes.rb
Rails.application.routes.draw do
resource :session, only: %i[new create destroy]
+ resource :registration, only: %i[new create]
The registrations_controller
will be a lot like sessions_controller
, but instead of finding a User, we will create one.
# app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
allow_unauthenticated_access
before_action :resume_session, only: :new
rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_url, alert: "Try again later." }
def new
redirect_to root_url, notice: "You are already signed in." if authenticated?
end
def create
user = User.new(params.permit(:email_address, :password))
if user.save
start_new_session_for user
redirect_to after_authentication_url, notice: "Signed up."
else
redirect_to new_registration_url(email_address: params[:email_address]), alert: user.errors.full_messages.to_sentence
end
end
end
Now you can add a “Sign up” link in your navbar:
<%= link_to 'Home', root_path %>
<%= link_to 'Dashboard', dashboard_path %>
<% if authenticated? %>
<%#= Current.session %>
<%= Current.user.email_address %>
<%= button_to 'Sign out', session_path, method: :delete %>
<% else %>
<%= link_to 'Sign in', new_session_path %>
+ <%= link_to 'Sign up', new_registration_path %>
<% end %>
Create the sign_up
form. It will be the same as the sign_in
form, just with a different url
:
# app/views/registrations/new.html.erb
<h1>
Sign up
</h1>
<%= form_with url: registration_url do |form| %>
<div>
<%= form.email_field :email_address, required: true, autofocus: true, autocomplete: "email", placeholder: "Enter your email address", value: params[:email_address] %>
</div>
<div>
<%= form.password_field :password, required: true, autocomplete: "new-password", placeholder: "Create a password", maxlength: 72 %>
</div>
<%= form.submit "Sign up" %>
<% end %>
Finally, validate User email address to show validation errors:
# app/models/user.rb
+ validates :email_address, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
That’s it! Now your users can both sign in and sign up to your app.
Although you will most likely want to add password reset flow & email confirmation flow to make this solution viable for a real app.
I still recommend using gem Devise for email-password authentication.
Did you like this article? Did it save you some time?