前段日子给huaborn网站启用了sidekiq用于rails异步发送邮件等操作,测试时发现发送忘记密码邮件时发送的token即url参数为空,几经查询发现了新的bug.主要出现问题为sidekiq异步操作导致,解决后特此记录。
个人原创,版权所有,转载请著名原文出处并保留原文链接:
http://www.embbnux.com/2015/08/21/rails_use_sidekiq_send_email_bug_solve/
一、问题的出现
首先讲讲我的激活码代码结构:
一个user model,数据库字段为digest,为随机生成的token加密后存储,token并不存储,为虚拟字段,只在发送时出现,保证了安全性。token利用邮件发送给用户。
class User < ActiveRecord::Base attr_accessor :token validates :digest, presence: true end
一开始不异步发送邮件
@user.create_digest UserMailer.reset_email(@user) #邮件输出token <%= @user.token %>;
不用异步发送邮件操作的话上面代码运行正常。
二 启用sideki异步发送邮件输出数据异常
UserMailer.delay.reset_email(@user) #或者 UserMailer.reset_email(@user).deliver_later
发现邮件输出数据@user.token一直为空,收到邮件后没数据
三 问题的解决
几经查询发现了问题所在,因为token为用户model的虚拟字段,并不存储于数据库中,而使用sidekiq异步运行程序是,传给sidekiq的为函数和函数参数,其中的@user model作为参数,并没有把@user整个model数据都传给sidekiq, sidekiq执行程序时需要重新从数据库中加载model,这里的虚拟字段token为空,所以数据渲染输出为空。
解决方法为传递参数时不要传@user整个model,而是直接传递code,即:
UserMailer.delay.reset_email(@user.token) #或者 UserMailer.reset_email(@user.token).deliver_later #输出 <%= token %>
这样token就会被保存在传递给token的参数中,运行时可以被找到不会丢失。
问题就这样被解决了,哈哈。