2017-01-06 18 views
0

私はDevisesでレールを使用していますconfirmable。ユーザーがサインアップすると、Deviseは自動的に確認メールを送信します。 3日後に確認されなかった場合は、別の確認メールと新しいトークンを送信します。この2番目のメールの後でもまだ確認しない場合は、もう送信しないでください。確認していないユーザーに対して、Devise確認メールを自動的に再送するにはどうすればよいですか?

  • 1日目:タイムライン上にマッピングされたユーザーサインアップ&は確認メールを受け取ります。ユーザーが
  • 3日目を確認していません
  • 2日目を確認しない確認するためにそれらを促す別のメールを送信を。確認していません
  • 第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 

は、改善のための任意のヘルプや提案に感謝:

は、ここで私がこれまで持っているものです。あなたは、これは水曜日に実行する場合は、月曜日に登録されているすべての未確認のユーザーを取得し、

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

:あなたは一日一回、ワーカーを実行しようとしている場合

+0

バッチでレコードをロードする '.find_each'を使用すると、使用可能なメモリを使い果たしてしまう可能性があります。 – max

答えて

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!を使用する必要があり、作業員が(原因ダイナモの再起動に例えば)事故により一日に複数回実行した場合、人は潜在的可能性はほぼ完璧です確認メールが多すぎます。

今私が理解しようとしているのはwhy my tests aren't workingです。

関連する問題