如何使用delayed_job使Rails 3.0中的ActionMailer异步运行?遇到ArgumentErrors。

10

我正在尝试延迟发送一封通知电子邮件给用户,当他们注册我的应用程序时。这些电子邮件使用我调用的InitMailerActionMailer发送。 我尝试延迟作业的方法是使用collectiveidea的delayed_jobhttps://github.com/collectiveidea/delayed_job。为此,您可以看到我在定义initial_email方法后指定了handle_asynchronously

class InitMailer < ActionMailer::Base
  default :from => "info@blahblahblah.com"

  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

然而,我在我的日志文件"delayed_job.log"中遇到了一个参数错误:

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

提供信息,电子邮件是在控制器中使用以下代码发送的:

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

此外,当我没有设置延迟时,邮件可以正常发送(除了等待gmail服务器会导致我的应用程序变慢的事实)。请问是什么原因导致了错误?我该如何使延迟邮件能够正确发送?

1个回答

10

由于Rails3实现邮件发送的方式,导致需要使用一些不寻常的方法来处理延迟任务。例如,你可能已经看到了,在延迟发送邮件时,需要编写以下代码:

```
Delayed::Job.enqueue YourMailer.delayed_method(@some_arguments)
```

请注意,上述代码中的"YourMailer.delayed_method"是邮件类中要执行的延迟方法的名称,而"@some_arguments"是传递给该方法的参数。

 ExampleMailer.delay.example(user)

通常情况下,您需要在方法定义之后编写handle_asynchronously,但在邮件程序中,这个声明(由于某种原因)会阻止延迟作业的工作。

因此,在此代码中,完全删除该声明:

 class InitMailer < ActionMailer::Base
   default :from => "info@blahblahblah.com"

   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

谢谢!这是解决我的问题的答案。希望我能和像你这样的人一起工作! - geb2011
太棒了。我刚刚浪费了两天时间来解决这个问题(还有一个拦截器导致失败的问题,以及 Gmail 不想接受来自我的开发环境的电子邮件)。 - Clay
我会在开发环境中使用Mandrill代替Gmail来发送邮件。 - netwire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接