How to make Devise redirect after confirmation

后端 未结 6 804
囚心锁ツ
囚心锁ツ 2020-12-02 13:07

How can I create an after-confirmation redirect in Devise?

Before I added the confirmation module the custom after_sign_up_path worked fine

相关标签:
6条回答
  • 2020-12-02 13:38

    I just went through all of this and none of the other answers worked (2015-04-09 with devise 3.4.1).

    After signup, I wanted the user to be redirected to the login page with a message about a confirmation email. To get that working, here's what I had to do:

    class RegistrationsController < Devise::RegistrationsController
    
    protected
      # This is the method that is needed to control the after_sign_up_path 
      # when using confirmable. 
      def after_inactive_sign_up_path_for(resource)
        new_user_session_path
      end
    
    end
    

    I just found this comment which would have sent me exactly where I needed to be much sooner.

    Here is the reference to the after_inactive_sign_up_path_for that mentions Niels: Devise wiki – marrossa Nov 13 '12 at 3:38

    0 讨论(0)
  • 2020-12-02 13:43

    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.

    0 讨论(0)
  • 2020-12-02 13:52

    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.

    0 讨论(0)
  • 2020-12-02 13:54

    The confirmation_path also must be configured while working with refinerycms integrated in a rails app

    0 讨论(0)
  • 2020-12-02 13:57

    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" }
    
    0 讨论(0)
  • 2020-12-02 13:59

    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" }
    
    0 讨论(0)
提交回复
热议问题