See it working at https://single-page-signup-signin.herokuapp.com/
A demo application for single page login registration using devise and without overriding any devise standard controller methods (index, new, show, edit, delete, destroy)
- Of course Devise will have to be installed in the app. Also it's convenient for the developers to generate the views of devise. It helps to do everybody's favourite task (copy & paste). Generate a user model.
- Generate a controller (in this example
dashboards_controller
) that can be used as the root directory after authentication. It uses a show method for this task. Set the root path asroot to: 'dashboards#show'
and appendbefore_action :authenticate_user!
to thedashboards_controller
. Also it's good to be able to logout. Adding the following code snippet to views/dashboards/show.html.erb does just that.<h2>Hello <i><%= @user.email %></i></h2> <% if user_signed_in? %> <li> <%= link_to('Logout', destroy_user_session_path, method: :delete) %> </li> <% else %> <li> <%= link_to('Login', new_user_session_path) %> </li> <% end %>
- Now the app needs a single controller and view to render the registration and login form. Generate a new controller and view (in this example
contents_controller
andcontents#new
). Now copy and paste (cause we love it) the contents ofapp/views/users/registrations/new.html.erb
andapp/views/users/sessions/new.html.erb
toapp/views/contents/new.html.erb
(only if you follow me blindly otherwise different) respectively. Now the views should not find resources. To fix this, add following code toapp/helpers/contents_helper.rb
module ContentsHelper def resource_name :user end def resource @resource ||= User.new end def devise_mapping @devise_mapping ||= Devise.mappings[:user] end end
- Now some housekeeping stuffs. First of all generate
RegistrationsController
that inheritsDevise::RegistrationsController
andSessionsController
that inheritsDevise::SessionsController
. Configure theroutes.rb
like the following.Rails.application.routes.draw do root to: 'dashboards#show' devise_for :users, controllers: { registrations: 'registrations', sessions: 'sessions' } resources :contents end
The following cases should be realized. These are discussed and the way to overcome them are shown in the steps to follow.
- When user logs out, the browser does not get redirected to the
content#new
rather it is redicted tosessions#new
. To Overcome that add the following code to yourapp/controllers/application_controller.rb
protect_from_forgery with: :exception private def authenticate_user! unless user_signed_in? redirect_to new_content_path end end
- When there is some sort of failure in login process, it does not get redirected to the
content#new
rather it is redicted tosessions#new
. Following steps should overcome it.- Create
lib/custom_failure.rb
and add the following codeclass CustomFailure < Devise::FailureApp def redirect_url new_content_path end def respond if http_auth? http_auth else redirect end end end
- Configure the
config/initializers/devise.rb
with the followingconfig.warden do |manager| manager.failure_app = CustomFailure end
- Lastly, add the library file to the
config/application.rb
config.autoload_paths << Rails.root.join('lib')
- Create