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

Devise invitable:重发自定义邀请时如何获取有效token?

解决重发邀请时无法获取raw_invitation_token的问题

问题原因

你在调用User.invite!时设置了u.skip_invitation = true,这个配置会让Devise Invitable跳过整个邀请流程,包括生成并存储邀请token,所以user.raw_invitation_token会返回nil。

可行解决方案

方案1:手动生成并保存邀请token

直接在用户实例上手动生成未加密的邀请token,确保持久化后再传递给邮件任务:

def resendInvitation
  user = User.find(params[:id])
  # 生成新的未加密邀请token(自动同步加密后的token到数据库)
  user.generate_invitation_token
  # 保存用户,确保token被写入数据库
  user.save(validate: false) # 若无需验证用户其他字段,可添加此参数跳过验证
  p "TOKEN: #{user.raw_invitation_token}" # 此时能获取有效token
  SendNewClientEmail.perform_later(user.id, user.raw_invitation_token)
end

方案2:保留默认邀请流程,拦截Devise默认邮件

如果你希望沿用Devise Invitable的原生流程,只需阻止它发送默认邮件,这样invite!会自动生成token:

  1. 在User模型中添加回调拦截默认邮件:
class User < ApplicationRecord
  devise :invitable, # 你的其他Devise模块

  after_invitation_created :skip_devise_default_email

  private

  def skip_devise_default_email
    # 清空邀请发送时间,阻止Devise触发默认邮件
    self.invitation_sent_at = nil
  end
end
  1. 修改重发邀请方法,移除skip_invitation配置:
def resendInvitation
  user = User.find(params[:id])
  # 调用invite!自动生成token,同时通过模型回调阻止默认邮件
  user = User.invite!(email: user.email, location_id: user.location_id)
  p "TOKEN: #{user.raw_invitation_token}" # 正常获取token
  SendNewClientEmail.perform_later(user.id, user.raw_invitation_token)
end

关键注意点

  • raw_invitation_token是临时字段,仅在生成token的当前对象实例中可用。一旦用户被重新查询(比如Job中通过ID查找),这个字段会变为nil,所以必须在生成后立即传递给Job。
  • 确保User模型已正确配置Devise Invitable,数据库迁移已添加invitation_token、invitation_created_at等必要字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:43:11