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:
- 在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
- 修改重发邀请方法,移除
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
相关产品推荐
相关产品推荐

