我正在使用Rails 3.2.13
,Devise 3.2.4
。用户注册后,生成确认链接。
localhost:3000/users/confirmation?confirmation_token=HpPHitLtV3CnLy2z1ZmQ
点击确认链接后,我想重定向到导师/新动作。
但在确认后,它会重定向到 / users / sign_in ,这是我不想要的。以下是我到目前为止的代码。
路线
devise_for :users
devise_for :users, :controllers => { :confirmations => 'confirmations' }
从Devise :: ConfirmationsController
创建了Confirmations控制器和覆盖class ConfirmationsController < Devise::ConfirmationsController
protected
def after_confirmation_path_for(resource_name, resource)
if resource.has_role? :user
redirect_to new_mentor_path("account_id")
else
root_path
end
end
end
在ConfirmationsController中,我可能需要添加一些额外的代码。请提供一些解决方案。
在应用程序控制器中,我已经放置了以下代码,这些代码在成功登录后将我带到导师/学生家中
def after_sign_in_path_for(resource_or_scope)
if resource_or_scope.is_a?(User)
if current_user.user_type == "mentor"
home_mentors_path(:account_id => current_user.account_id)
else
home_students_path(:account_id => current_user.account_id)
end
end
端
def after_sign_up_path_for(resource_or_scope)
root_path
end
一般来说,逻辑是这样的,但我不知道如何用Devise做到这一点。
def activate
@user = User.where("activation_code = ?","#{params[:id]}").first
if !@user.blank?
if @user.created_at < 24.hours.ago
if @user and @user.activate
cookies[:user_id]=@user.id
if @user.user_type == "student"
redirect_to new_student_path
else
redirect_to new_mentor_path
end
else
@user.destroy
redirect_to "/"
end
else
@user.destroy
redirect_to "/"
end
else
redirect_to "/"
end
端
答案 0 :(得分:1)
如果你看devise github repository。这是单击确认链接时调用的方法
# GET /resource/confirmation?confirmation_token=abcdef
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
yield resource if block_given?
if resource.errors.empty?
set_flash_message(:notice, :confirmed) if is_flashing_format?
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
else
respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
end
end
现在你已经覆盖了设计 after_confirmation_path 这样的方法
protected
def after_confirmation_path_for(resource_name, resource)
if resource.has_role? :user
redirect_to new_mentor_path("account_id")
else
root_path
end
end
哪个好,设计会重定向到你的new_mentor_path,但在你的导师控制器中你需要一个文件管理器来检查身份验证,如:
before_action :authenticate_user! #this will check if your user is signed in or not and if not it'll redirect you
因为@Rich Peck
建议您在重定向到new_mentor_path 之前,基本上还需要覆盖您的show动作以便用户登录
在您的展示操作中,您可以执行以下操作以确保您的用户已登录
# GET /resource/confirmation?confirmation_token=abcdef
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)
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
else
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
end
end
还在你的after_confirmation_path中注意到你有redirect_to new_mentor_path("account_id")
为什么你在路径中将account_id作为字符串传递?
如果您的account_id是一个整数,那么您必须先在show action中设置它,然后调用after_confirmation_path,如 respond_with_navigational(resource){redirect_to after_confirmation_path_for(resource_name,resource,account_id)}。您还必须更改after_confirmation_path的定义,如:
def after_confirmation_path_for(resource_name, resource, account_id)
if resource.has_role? :user
redirect_to new_mentor_path(account_id)
else
root_path
end
end
答案 1 :(得分:0)
经过研究,我发布了问题的正确答案。
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) #This will detect if user is logged in.
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
else
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
end
end
protected
def after_confirmation_path_for(resource_name, resource)
if resource.is_a?(User)
new_mentor_path("account_id") #do not provide redirect_to which is already taken in respond_with_navigational(resource)
else
root_path
end
end
end
我评论devise_for:用户,因为每次点击确认链接并且确认控制器没有调用并重定向到登录路径时,此路由都在调用。以下是我面临的问题的主要解决方案。
# devise_for :users
devise_for :users, :controllers => { :confirmations => 'confirmations' }