PlankTon
PlankTon

Reputation: 12605

Rails 3/delayed_job - Wanted: Basic example of delayed mail

I've been trying to figure out how to send delayed mail using delayed_job with rails 3. I've tried pretty much every combination of feasible possibilities I can think of - I can get the mail to run in the background, I just can't get it to delay the sending to a future time. The delayed_jobs table in the db clears the tasks, the log says 'sent', the delayed_job task processor picks up the task & says sent without failure...but the mail is either:

if I try to send in the future.

If anyone could offer a bare-bones example of a rails 3 delayed_job that sends mail in the future, I'd be really appreciative. I'm sure lotsa folks do this so I suspect I'm missing something obvious. One (of countless) combinations I've tried below:

delayed_job: 2.1.2 rails: 3.0.3 actionmailer: 3.0.3

Controller:

class TestmailerController < ApplicationController
  def index
    Testmailer.delay.test_mail
  end

end

Mailer:

class Testmailer < ActionMailer::Base
  def test_mail
    mail(:to => '([email protected]', :from => '(removedforprivacy)@gmail.com', :subject => 'Testing Delayed Job', :content_type => 'text/plain').deliver
  end
  handle_asynchronously :test_mail, :run_at => Proc.new { 2.minutes.from_now }


end

relevant mail part of config/environments/development.rb:

  # Don't care if the mailer can't send
  config.action_mailer.raise_delivery_errors = true

  # Print deprecation notices to the Rails logger
  config.active_support.deprecation = :log

  config.action_mailer.default_url_options = { :host => 'localhost:3000' }

  ActionMailer::Base.smtp_settings = {
    :address => "smtp.gmail.com",
    :port => 587,
    :domain => "gmail.com",
    :user_name => "(removedforprivacy)",
    :password => "(removedforprivacy)",
    :authentication => "plain",
    :enable_starttls_auto => true
  }

Job command:

rake jobs:work

Upvotes: 5

Views: 6680

Answers (3)

andrea
andrea

Reputation: 3505

Both using the .delay method and setting handle_asynchronously :test_mail is redundant. Try removing the .delay method from your code. use simply

Testmailer.test_mail   # without .deliver due to a delayed_job issue

However, I ran some test on your configuration and when using sqlite, run_at is simply ignored (do not know why), but when using mysql2 everything works fine.

Upvotes: 1

Ryan Buckley
Ryan Buckley

Reputation: 121

I found in Rails 3 with mongoid that removing the handle_asynchronously line gets it to work. I was having all kinds of problems, and it appeared that delayed_job wasn't recognizing any objects within my Emailer class. Removing handle_asynchronously fixed it.

Upvotes: 1

Will
Will

Reputation: 146

I agree with andrea - I was having this exact problem, and after switching my local development database from sqlite to mysql, I can run code like

Emailer.delay({:run_at => 5.minutes.from_now}).welcome(@user)

and it sends the email 5 minutes later. Note that you might need a bigger delay than five minutes (in case of time zone weirdness) to be sure it is working.

Upvotes: 13

Related Questions