You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Devise框架下如何在确认邮件中添加账户删除选项

解决Devise确认邮件中添加删除账户链接的问题

嘿,我来帮你搞定这个问题!你遇到的undefined method 'user_registration_path'错误,主要是路由名称不对,再加上邮件环境里的一些特殊限制,咱们一步步来解决:

1. 先找对正确的路由名称

首先打开终端跑一下 rails routes | grep registration,看看用户注册相关的路由条目。根据你的routes.rb配置,删除账户对应的DELETE路由应该是这样的:

DELETE /users(.:format)       users/registrations#destroy

对应的路由助手是 destroy_user_registration_path,而不是你之前用的user_registration_path(那个是对应GET/PUT请求的路由,不是删除用的)。

2. 处理邮件里不能发DELETE请求的坑

邮件客户端不支持JavaScript,所以你原来写的:method => :destroy在邮件里根本不会生效——点击链接默认是发GET请求,根本触发不了删除操作。这里有两个方案:

方案一:做个删除确认页面(推荐,符合RESTful规范)

这是生产环境的最佳实践,步骤如下:

  • 先修改你的users/registrations_controller.rb,新增一个确认页面的action,同时调整删除逻辑,支持用确认token验证身份(毕竟用户还没登录):
class Users::RegistrationsController < Devise::RegistrationsController
  # 新增删除确认页面的action
  def delete_confirmation
    @user = User.find(params[:id])
  end

  # 重写destroy action,支持未登录用户用token删除未确认账户
  def destroy
    # 优先用当前登录用户,否则用token找用户
    @user = current_user || User.find_by(confirmation_token: params[:confirmation_token])
    
    if @user&.destroy
      redirect_to root_path, notice: '账户已成功删除'
    else
      redirect_to root_path, alert: '删除账户失败,请重试'
    end
  end
end
  • 然后在routes.rb里加一条确认页面的路由:
devise_scope :user do
  get "/apply" => "users/registrations#new", as: "new_user_registration"
  # 新增删除确认页面的路由
  get "/users/:id/delete_confirmation" => "users/registrations#delete_confirmation", as: "user_delete_confirmation"
end
  • 接着修改你的confirmations_instructions.html.erb模板,把删除链接指向这个确认页面:
<p><%= link_to 'Accept this writer', confirmation_url(@resource, confirmation_token: @token) %></p>
<p><%= link_to "Delete this writer", user_delete_confirmation_path(@resource, confirmation_token: @token) %></p>
  • 最后创建app/views/users/registrations/delete_confirmation.html.erb页面,放一个发送DELETE请求的表单:
<h1>确认删除账户</h1>
<p>你确定要删除这个未确认的账户吗?</p>
<%= button_to "确认删除", destroy_user_registration_path(@user, confirmation_token: params[:confirmation_token]), 
              method: :delete, data: { confirm: "Are you sure you want to delete your account?" } %>

方案二:临时允许GET请求删除(仅测试用,不推荐生产)

如果只是想快速测试功能,可以临时修改删除逻辑支持GET请求,但这不符合RESTful规范,容易有安全风险:

  • 修改registrations_controller.rb的destroy action:
def destroy
  @user = User.find_by(confirmation_token: params[:confirmation_token])
  if @user&.destroy
    redirect_to root_path, notice: '账户已删除'
  else
    redirect_to root_path, alert: '操作失败'
  end
end
  • 然后修改邮件模板的链接:
<p><%= link_to "Delete this writer", destroy_user_registration_path(@resource, confirmation_token: @token), confirm: "Are you sure?" %></p>

3. 确保邮件模板能调用路由助手

如果还是提示路由助手未定义,那就在Devise的邮件器里手动引入路由模块。修改app/mailers/devise/mailer.rb:

class Devise::Mailer < Devise.parent_mailer.constantize
  include Rails.application.routes.url_helpers
  include Devise::Controllers::UrlHelpers # 确保加载Devise的路由助手

  # 保留原有的其他代码
end

4. 关键:用token验证删除权限

因为用户还没确认账户,肯定没登录,所以删除操作必须靠邮件里的confirmation_token来验证身份,确保只有收到邮件的人才能删除这个账户——这就是为什么我们在destroy action里要通过params[:confirmation_token]去找用户的原因。

按照上面的步骤调整后,应该就能正常工作了!

内容的提问来源于stack exchange,提问作者Mia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:19:25