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" }