How to make Devise redirect after confirmation

The solution given by @Lee Smith is working perfectly but I wish to add a little addition: We don't need to add the new and create actions while overriding the Devise confirmations controller for this case:

class ConfirmationsController < Devise::ConfirmationsController
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_navigational_format?
      sign_in(resource_name, resource)
      respond_with_navigational(resource){ redirect_to your_desired_redirect_path }
    else
      respond_with_navigational(resource.errors, status: :unprocessable_entity){ render_with_scope :new }
    end
  end
end

Then in the route file, just add routing for the confirmations controller.

devise_for :users, controllers: { confirmations: "confirmations" }

A less intrusive way of achieving this might be just overriding the after_confirmation_path_for method of Devise::ConfirmationsController.

Create a new confirmations_controller.rb in app/controllers directory:

class ConfirmationsController < Devise::ConfirmationsController

  private

  def after_confirmation_path_for(resource_name, resource)
    your_new_after_confirmation_path
  end

end

In config/routes.rb, add this line so that Devise will use your custom ConfirmationsController. This assumes Devise operates on users table (you may edit to match yours).

devise_for :users, controllers: { confirmations: 'confirmations' }

Restart the web server, and you should have it.


Essentially, you want to change around line 25 of Devise's ConfirmationsController.

This means you need to override the show action modifying the "happy path" of that if statement in the show action to your heart's content:

class ConfirmationsController < Devise::ConfirmationsController
  def new
    super
  end

  def create
    super
  end

  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_navigational_format?
      sign_in(resource_name, resource)
      respond_with_navigational(resource){ redirect_to confirmation_getting_started_path }
    else
      respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
    end
  end
end

And a scoped route for it (I put the view and action in the registrations controller but you can change it to whatever):

devise_for :users, controllers: { confirmations: 'confirmations' }
devise_scope :user do
  get '/confirmation-getting-started' => 'registrations#getting_started', as: 'confirmation_getting_started'
end

The default show action is referring to the protected after_confirmation_path_for method, so as another option, you could just modify what that method returns.


Have you checked the Devise wiki? It explains how to do this, with the after_signup_path_for being the path to define in your case.

From the wiki:

Make a new controller "registrations_controller.rb" and customize the appropriate method:

class RegistrationsController < Devise::RegistrationsController
  protected

  def after_sign_up_path_for(resource)
    '/an/example/path'
  end
end

Then add a route to use it:

Modify config/routes.rb to use the new controller

devise_for :users, :controllers => { :registrations => "registrations" }