This little howto describes, how to use ar_mailer to schedule emails for future delivery.
Sorry for the bad formatting. Might change it someday…
1) Migrate emails table and add needed fields
add_column :emails, :various, :string #holds classname and id of any object you want to
add_column :emails, :type, :string #type of email
add_column :emails, :date_to_send, :date #date to send that mail
2) Override “def find” in email.rb
def self.find(*args)
with_scope(:find=>{ :conditions=>["(date_to_send IS NULL OR date_to_send <= ?)", Date.today] }) do
super(*args)
end
end
3) Create DelayedEmail class, inherting Email
class DelayedEmail < Email
before_save :set_due_date
before_save :set_various_field
@@days_before_sending = 21 #default is 3 weeks after creation of various object
@@various_class = nil
def set_due_date
self.date_to_send = Date.today + @@days_before_sending
end
def set_various_field
name = @@various_class.class.to_s + "_" rescue "NOCLASS_"
id = @@various_class.id.to_s rescue "0"
self.various = name + id
end
#tell email to which object it belongs. might be important for future deletion of unsent mails
def self.set_various_class(c)
@@various_class = c
end
#tell email how many days shall pass by before sending email
def self.set_days(days)
@@days_before_sending = days
end
end
4) Modify ar_mailer standard emailer class in controller before delivery and set it back afterwards
DelayedEmail.set_days(10)
DelayedEmail.set_various_class(SOMEOBJECT)
ActionMailer::ARMailer.email_class=DelayedEmail
#Let any mailer send an email through this class
#eg. Mailer.deliver_mymail(...)
ActionMailer::ARMailer.email_class=Email