设计确认帐户并设置密码

Devise confirm account and set password

在我的应用程序中,我使用了 Devise 和 Active Admin。用户在没有密码的管理区域中创建,然后他们会收到一封带有 link 的邮件到确认页面,他们可以在其中输入新帐户的密码。

这是确认控制器:

class ConfirmationsController < Devise::ConfirmationsController

  def show
    @original_token = params[:confirmation_token]
    digested_token = Devise.token_generator.digest(self, :confirmation_token,params[:confirmation_token])
    self.resource = resource_class.find_by_confirmation_token(digested_token) if params[:confirmation_token].present?
    super if resource.nil? or resource.confirmed?
    render :layout => "internal"
    end


  def confirm
    digested_token = Devise.token_generator.digest(self, :confirmation_token, params[resource_name][:confirmation_token])
    self.resource = resource_class.find_by_confirmation_token(digested_token) if params[resource_name][:confirmation_token].present?
    if resource.update_attributes(params[resource_name].except(:confirmation_token).permit(:email, :password, :password_confirmation)) && resource.password_match?
      self.resource = resource_class.confirm_by_token(params[resource_name][:confirmation_token])
      set_flash_message :notice, :confirmed
  sign_in_and_redirect(resource_name, resource)

    else
      @original_token =  params[resource_name][:confirmation_token]
      render :action => "show", :layout => "internal"
    end    
    
  end
  
end

相关路线:

  devise_for :users, :path_prefix => 'd', :controllers => {:confirmations => 'confirmations'}

  devise_scope :user do
    patch "/confirm" => "confirmations#confirm"
  end

当用户在后台单击激活 link 时,它会将帐户设置为在数据库中确认,但我没有被重定向到 confirmations/show 来设置密码,而是开始了这个线渲染:布局=>“内部”

Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".

为什么会这样?

在你的ConfirmationsController中:

class ConfirmationsController < Devise::ConfirmationsController

  def show
    @original_token = params[:confirmation_token]
    digested_token = Devise.token_generator.digest(self, :confirmation_token,params[:confirmation_token])
    self.resource = resource_class.find_by_confirmation_token(digested_token) if params[:confirmation_token].present?
    # here you call super if resource is nil or confirmed
    # super calls the show action of Devise::ConfirmationController
    # it results with the first render (but doesn't call any return)
    super if resource.nil? or resource.confirmed?
    # after super is finished you continue and render layout internal
    # (again, since it has happened in the parent controller already)
    render :layout => "internal"
  end
...

您可以在他们的 github 页面上查看 Devise::ConfirmationsController 中到底做了什么:https://github.com/heartcombo/devise/blob/master/app/controllers/devise/confirmations_controller.rb

如果你想呈现 confirmations/show 页面,那么只需删除

render layout: 'internal'

行。