Stef Coetzee

A sensible guideline for web applications is to keep the product decoupled from marketing. This prevents changes on the one from adversely affecting the other. A straightforward way to do this: deploy the marketing site on the apex domain (e.g. example.com) and the application on a subdomain (e.g. app.example.com).

Since we have the marketing landing page separate from the application, it’d be a waste to have another non-functional page inside the application users have to click through. We want the first thing users see inside the app to be functional. How could we do this in Rails? If you use Devise for authentication, and I recommend that you do, there might just be a simple solution.

Let’s assume user authentication is required for any activity inside the application. We’ll add the authenticate_user! function to ApplicationController as follows:

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :authenticate_user!

  ...
end

Next, we’ll change the root route (try saying that three times fast) in routes.rb:

# config/routes.rb

Rails.application.routes.draw do
  devise_for :users

  devise_scope :user do
    root 'devise/sessions#new'
  end

  ...
end

At this point, after logging in the root route spirals into an infinite redirect, which obviously doesn’t resolve. This bit tripped me up for a second (or two). Enter Stack Overflow. I happened upon this question first, which has the same problem we’re stuck on. No bueno. Thanks to user Jngai1297, we click through to this answer, where Rajdeep Singh lands the finishing blow on our infinite-redirect foe. Turns out we have another adjustment to make to ApplicationController:

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :authenticate_user!

  def after_sign_in_path_for(user)
    # your path goes here
    user_posts_path(user) # as an example
  end

  ...
end

Now visiting the app will direct users to the sign-in page, and signing out will do likewise. To remove the “You are already signed in.” flash notification users receive when visiting the root route after signing in, adjust devise.en.yml like so:

# config/locales/devise.en.yml

en:
  devise:
    ...
    failure:
      already_authenticated: ""
      ...

With that, you can resume building your kickass web app. 🙂

Thanks for reading!

#Rails #Devise

Published:
Join the mailing list
Get new posts in your inbox. Unsubscribe anytime.