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. 🙂