Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one use delayed_job to make an Rails 3.0 ActionMailer run asynchronously? Encountering ArgumentErrors

I'm trying to delay a notification email to be sent to users upon signing up to my app. The emails are sent using an ActionMailer which I call InitMailer. The way I am trying to delay the jobs is using collectiveidea's delayed_job https://github.com/collectiveidea/delayed_job. To do this you can see that i specify handle_asynchronously after defining the method initial_email:

class InitMailer < ActionMailer::Base
  default :from => "[email protected]"

  def initial_email(user)
    @user = user
    @url = "http://www.blahblahblah.com"
    mail(:to => user.email,
         :subject => "Welcome to my website!"
         ) 
  end

  handle_asynchronously :initial_email
end

However, I encounter an argument error in my log file "delayed_job.log":

Class#initial_email failed with ArgumentError: wrong number of arguments (1 for 0) - 5 
failed attempts

For your information, the email is sent in a controller using the line:

@user = InitUser.new(params[:init_user])
InitMailer.delay.initial_email(@user)

Additionally, when I set up my code without the delay, the emails were sent out without problem (except for the fact that it slowed down my app waiting for gmail servers)

Where is causing the errors here? How can I get the delayed mail to send properly?

like image 979
geb2011 Avatar asked Jun 29 '11 04:06

geb2011


1 Answers

Due to the way that Rails3 implements mailers, there are some unusual workarounds for delayed_jobs. For instance, you have seen that to delay the mailing, you write

 ExampleMailer.delay.example(user)

While typically you would have to write handle_asynchronously after the method definition, in the case of mailers this declaration (for some reason) prevents that delayed job from working.

So in this code, drop the declaration entirely:

 class InitMailer < ActionMailer::Base
   default :from => "[email protected]"

   def initial_email(user)
     @user = user
     @url = "http://www.blahblahblah.com"
     mail(:to => user.email,
          :subject => "Welcome to my website!"
          ) 
   end

   #No handle_asynchronously needed here
 end
like image 110
jay Avatar answered Oct 31 '22 21:10

jay