How to have 2 different root paths

I know I can use authenticated user as a root and default root as an option. But my use case is I have a wizard and using wicked gem.

  1. when user signup he will be asked to confirm the account
  2. after confirmation (for the first time sign in only) he should be redirected to the wizard
  3. else make him go to dashboard#show

things I tried

  1. In registrations_controller.rb
    def after_sign_up_path_for(_resource)
    if current_user.sign_in_count == 1

  2. in dashboard_controller.rb
    if current_user.sign_in_count == 1

  3. in routes.rb
    authenticated :user do
    root to: ‘dashboard#show’, as: :authenticated_root
    root to: ‘home#landing’

In step3 route overriding the registrations_controller values
def after_sign_up_path_for(_resource)

for now, I have removed the :confirmable to clean up the project but eventually I need it

Based on the code snippets you provided, it looks like you want two different things.

  1. An authenticated user to have a different root path than someone who isn’t logged in.
  2. A new user to be directed to a wizard to help them get started.

The first step you seem to have under control. It looks like you’re using Devise, and you can pretty easily create a new root path for a user who isn’t logged in.

The second part seems to be the place where you are running into the logic problem: “When is a good time to show a new user an onboarding wizard?”

It seems like you’re trying to use sign_in_count as a measure for someone needing a wizard to get started, but there will likely be a couple UX problems with this user flow.

What happens when a user signs up, sees a multi-step wizard form, but is in a rush or too busy to be bothered about this form right now? They log out, quit the browser, and return to it later. When they return to your app the wizard is no longer there and they have an empty account and a new UI they haven’t seen before? Most likely they will be lost, confused, and not properly be on-boarded into your app.

Unless they user has already paid for your app or absolutely need it, they likely won’t return.

I think you need a better way of deciding if a user needs a wizard or not.

Wizard logic on macOS

One of my favorite examples of this logic is with Apple’s macOS. When you log into a new Mac for the first time, the user is greeted with a friendly wizard to walk them through setting up their computer. Once they have finished setting up, their Mac will create a tiny file. /var/db/.AppleSetupDone

Every time the mac is started, it checks to see if that file is present. If the .AppleSetupDone file exists, it brings the user right to the login screen. If it doesn’t, the user will be brought to a wizard to set up their first Admin account.

If you want to rerun this wizard, you can simply delete the file and Apple will bring you back to the setup wizard.

I like this way more. This way, I can log in and out as many times as I want but I won’t be brought any further into the app than I am ready for.

Replicating this behavior.

I would direct the user to the wizard every time unless they have already finished the wizard.

In your situation, I would add a boolean column to my user’s table in the database called wizard_completed with a default value of false.

On the last step of my wizard, I would use the hidden_field form helper to change wizard_completed to true.

In the dashboard#show (or wherever your default “sign in” button leads), I would use the controller’s logic to redirect to the wizard if current_user.wizard_completed is false. This way the new user, logging in through the new site’s (at least it’s new to them) sign in path, should be greeted with the wizard until they have completed it.

Again, let me know if this helps.



It’s actually brilliant. Thanks a lot you actually saved me from huge dissapointment,

1 Like
  • I have created 2 boolean values step1 and step2
  • when the user completes step1 it has to become true
  • when the user completes the step2 this has to become true

I hope by this way I can pinpoint the place where the user left filling the form.
How to achieve this functionality. It’s a noob question It would really help me to move ahead.