3

I have simple mailer which sends user weekly digest and rake task which sends to all users this email, and it is pinned to heroku scheduler.

I want to send to user this email each week but only once a week, no matter how many times I run rake send_weekly_digest

Mailer

class DigestMailer < ActionMailer::Base
  include Resque::Mailer
  default from: "company@email.com"

  def weekly_digest(user_id)
    @user = User.find(user_id)

    mail :to => @user.email, :subject => "Weekly Digest"
  end
end

Rake Task

desc "Send weekly email digest"
task send_weekly_digest: :environment do
  User.all.each do |user|
    DigestMailer.weekly_digest(user.id).deliver
  end
end
tomekfranek
  • 6,852
  • 8
  • 45
  • 80

1 Answers1

5

Add a column to your users table called last_emailed_at or something similar and then update that column with a timestamp when you send the weekly digest.

Then in your rake task instead of saying User.all, only get users that haven't been emailed in the last week:

User.where("last_emailed_at < ?", 1.week.ago)
John
  • 4,362
  • 5
  • 32
  • 50
  • So should I add ``@user.last_emailed_at.touch`` to ``DigestMailer`` below ``mail :to => @user.email, :subject => "Weekly Digest"`` ? Is there a way to be sure that email was really delivered? – tomekfranek Dec 28 '12 at 15:13
  • The order in the controller shouldn't matter as the email will not be sent until deliver is called so I'd put it just before mail :to =>... I'm not sure about your second question. You have to trust that Rail's deliver method will send the email. You could add a validation on user email to check for ones that are invalid ex: hello#ok,com, or write some tests of the rake task to ensure it is sending emails correctly. – John Dec 28 '12 at 17:43