对于尚未确认的用户,如何自动重新发送设计确认电子邮件,但仅限一次?

时间:2017-01-06 00:50:24

标签: ruby-on-rails devise devise-confirmable

我正在使用Rails和Devise confirmable。当用户注册时,Devise会自动向他们发送确认电子邮件。如果他们在三天后仍未确认,我想向他们发送另一封带有新令牌的确认电子邮件。如果他们在第二封电子邮件后仍未确认,我们不应再发送邮件。在时间轴上映射:

  • 第1天:用户注册&收到确认邮件;不确认
  • 第2天:用户未确认
  • 第3天:发送另一封电子邮件,提示他们确认;不确认
  • 第4天:用户未确认;没有更多的电子邮件发送
  • 第5天:用户未确认;没有更多的电子邮件发送
  • 第6天:等。

我不想在我的用户模型中添加一个新列,用于跟踪他们已经发送确认电子邮件的次数,因为我认为我可以在每天使用我们已经运行的信息运行的工作人员中执行此操作有。然而,我正在努力使逻辑正确。

这是我到目前为止所拥有的:

# workers/resend_confirmation_worker.rb

class ResendConfirmationWorker
  include Sidekiq::Worker
  sidekiq_options queue: :resend_confirmation, retry: false

  def perform
    users = User.where('confirmation_sent_at IS NOT NULL and
                        confirmed_at IS NULL')
    users.each do |user|
      return if user.created_at < Time.zone.now - 4.days || user.created_at > Time.zone.now - 3.days
      user.resend_confirmation!
  end
end

# config/clock.rb

module Clockwork
  every(1.day, 'Resend confirmation') { ResendConfirmationWorker.perform_async }
end

感谢任何帮助或改进建议。

3 个答案:

答案 0 :(得分:2)

如果您打算每天运行一次这样的工作人员,您可能会使用以下内容:

User.where('
  confirmed_at IS NULL
  AND created_at >= ?
  AND created_at <= ?
', 2.days.ago.beginning_of_day, 2.days.ago.end_of_day)

如果你在星期三运行它,它将获取周一注册的所有未经证实的用户。

答案 1 :(得分:1)

d = 2.days.ago
users = User.where.not(confirmation_sent_at: nil)
            .where(confirmed_at: nil)
            .where(created_at: d.beginning_of_day..d.end_of_day)

users.find_each do |user|
  user.resend_confirmation!
end

答案 2 :(得分:0)

max发布的答案几乎是完美的,但您需要使用user.send_confirmation_instructions代替resend_confirmation!,并且如果工作人员偶然在一天中运行多次(例如由于dyno restart),人们可能会收到太多确认电子邮件。

现在我想弄清楚的是why my tests aren't working