Background:


There are several applications which has no signup pages. Application owner creates new account for user. This scenario best fits in Organisational Applications. So why don’t we create one organisational application. The application flow will be like this:

  • HR creates new user account
  • New user receives email to join the application
  • New user will create new password for his account
  • New user can access web application features i.e. holiday list

Let’s dive in the code for creating such application using Ruby on rails with me.

System requirements:

  • Ruby version: 2.3.1
  • Rails version: 5.0
  • Sqlite3 database

Setp 1: Create new rails Application


We will create brand new application to demonstrate this scenario. For creating new rails app run rails new admin_adds_user command on your terminal. It will create new directory with the same name with default Gems installation.

Step 2: Integrate Devise with new application


Let’s incorporate Devise Gem within application. Add gem 'devise’, ‘~> 4.2’ line to your Gemfile and run bundle install command. It will install Devise gem files to your local machine and you can access it’s modules and functions.

Now run rails generate devise:install command to generate some necessary files for Devise. It will generate following files;

config/initializers/devise.rb
config/locales/devise.en.yml

Former one contains basic configuration for devise. You can modify it. One most important setting needs to be configure is default URL. Devise generate some URLs and for that we need to define our base url. For thatwe will need following config.

# config/environments/development.rb
config.action_mailer.default_url_options = { host: localhost, port: 3000 }

This will work only for local development machine.

We want to integrate User model with devise so run rails generate devise user command for that. This will create user model and migration file with necessary column for the authentication. You can add more columns. For our scenario we are going to use confirmable module of devise. So comment out it from User model and also comment out column names from migration under the ## Confirmable heading. we will also add first_name and last_name column. Since we are not going to use reconfirmable module, update following configuration

# config/initializers/devise.rb
config.reconfirmable = false

We will need one more table(resource) named holiday lists. run rails generate scaffold HolidayList name date:datetime command to generate holiday_lists table with name and date. To create default holiday list, add this two lines to db/seed.rb file.

HolidayList.create(name: Christmas Day, date: 20171225)
HolidayList.create(name: Diwali, date: 20171019)

Now run rails db:migrate and rails db:seed to make our database ready.We will need so views for sending email confirmation and creating new password by user. You can develop these HTML template by your own or use easy way which devise provides. Generate corresponding devise views by running rails generate devise:views command. You can enhance these views by adding your custom HTML.

Let’s commit this changes and push it to Github

Step 3: Email Configuration


For sending email we need to configure it in our application. Open config/environments/development.rb file and add this code.

# mailer config
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { :host => ENV[host] }
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.default :charset => utf-8
ActionMailer::Base.smtp_settings =
 {
   :address => smtp.gmail.com,
   :port => 587,
   :authentication => :plain,
   :domain => gmail.com,
   :user_name => ENV[gmail_username],
   :password => ENV[gmail_password],
 }

Here you need to replace ENV[‘gmail_username’] and ENV[‘gmail_password’] with your email credentials. ENV[‘host’] will be your base URL as we discussed in above point. Best practice is to use environment variables to store sensitive information. This will make our mailing configuration ready. Let’s move on next step.

Step 4: Send Confirmation email


Now admin(HR in our case) will create new user, using create form. After creation of an User, an email will be forwarded to the new user. Let checkout what configuration is needed for this:

  1. Remove sign up link from `app/views/devise/_links.html.erb`
  2. Add `before_action :authenticate_user!` to application controller. This will check for user session before every action.
  3. Add some fields to user views so we can create new user (basic rails CRUD operations)
  4. Task to create one admin user (here I am not considering any roles. admin means first user only. I am going to write separate article for this.)

Now let’s plug confirmable module of devise. For that I have override devise’s Confirmations controller. You can find new confirmations controller here. Also updated routes file with,

devise_for :user, :controllers => { :confirmations => "confirmations" }
devise_scope :user do
  put 'user/confirmation', to: 'confirmations#update'
end

This will give us the necessary routes of confirmations controller to confirm user’s email. Add some methods to override devise modules in user model. Add one view file app/vies/users/passwords/edit.html.erb This file will be rendered when user will click on link sent in email. It is form to create new password. Last but not least add dotenv-rails gem to hide your credentials.

Source code at github: https://github.com/charusat09/admin_adds_user

I hope this will help you. Let me know about your thoughts or questions. You can connect me via chat button show at the botton right most corner. I will be really happy to answer your questions.

Apexit is technical articles series in which I will took one real world problem, will develop code for it together and share the source code with other people.