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
Would you mind submitting a patch to add this feature to ar_mailer? I’d love to include it.
Hi Eric,
sorry for the delay. There’s no change in ARMailer actually.
It’s all about 2 things:
1) adding a due date to the emails table
2) overriding the email find method to collect only due emails.
This works without changing anything in ARMailer.
Anyway, let me know if you need further information.
Cheers Matt