How to Add Usernames to Clearance
#Ruby-on-Rails #Authentication
In this tutorial we will cover adding a username to Clearance User models in Ruby on Rails. This post assumes you already completed Clearance setup instructions for your application and generated the appropriate models, views and controllers.
Generate Username Migration
Generate a migration to add an additional column to the users table called username:
$ bundle exec rails generate migration AddUsernameToUsers username
Open your newly generated migration file to ensure column addition is correct. In the code listing below, uniqueness and non-null validations are added to the database column configuration. These are optional, but, recommended.
class AddUsernameToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :username, :string, unique: true, null: false
end
end
On verifying your migration appears correct run the migration via Rails command line tools to apply the schema changes:
$ bundle exec rails db:migrate
Optional: Add Regular Expression Validations to User Model
As an optional addition, you may consider adding a regular expression validation check to the User model to ensure that username are consistent and sanitized. For example:
class User < ApplicationRecord
include Clearance::User
# Regular expression to allow letters, numbers, and underscore characters
VALID_USERNAME = /\A(\w|\.)+\z/.freeze
validates :username,
presence: true,
format: { with: VALID_USERNAME, message: 'Username can only include numbers, letters or underscores.' }
end
Override the UsersController
Generate a UsersController
for your application that inherits from Clearance::UsersController
in order to add additional behaviour:
class UsersController < Clearance::UsersController
# TODO
end
By default, Clearance::UsersController
defines create and new actions to create and render Users, respectively. In this child controller, will need override the strong parameters method user_from_params which is inherited from the parent class to include the username field form the migration. This strong parameters method is used by both the create and new actions in the parent class.
class UsersController < Clearance::UsersController
# -- snipped --
private
# Parameters used to create a new user record via +new+ and +create
def user_from_params
email = user_params.delete(:email)
username = user_params.delete(:username)
password = user_params.delete(:password)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.username = username
user.email = email
user.password = password
end
end
end
The above snippet is a modified version of the user_from_params
method in the parent class of Clearance::UsersController
that includes the username parameter.
Update Clearance Views to Include Username
With the UsersController
capable of accepting usernames in the payload sent by the view, we can update the user sign up view to include a username field during the sign up process. This assumes you are using stock views provided by Clearance via:
bundle exec rails generate clearance:views
<div id="clearance" class="sign-up">
<h2>Sign Up</h2>
<%= form_with model: @user do |form| %>
<div class="text-field">
<%= form.label :username %>
<%= form.text_field :username %>
</div>
<%= render partial: '/users/form', object: form %>
<div class="submit-field">
<%= form.submit %>
</div>
<div class="other-links">
<%= link_to "Sign In", sign_in_path %>
</div>
<% end %>
</div>
The primary modification is adding an addition field for the username above the partial template provided by Clearance. On addition, the sign up form will now include a username field to complete in order to sign up for the application:
Figure 1: The user sign up form containing the username field.