Rails 4 控制器不会调用我的 actionmailer class

Rails 4 controller won't call my actionmailer class

在我的 rails 4.2.5 (ruby 2.2.1) 应用程序中,我有一个非常简单的 actionmailer class。它甚至不发送邮件,只是发送 printf:

class UserTommail < ActionMailer::Base

  def joe
  printf("\n***** In Emails.joe")
  end

end

但是当我的控制器调用这个函数时,它从不执行 printf!

def contact_us
  printf("\n***** TOMS EMAILLER")
  UserTommail.joe()
  redirect_to(root_path(), :notice =>  "Your Contact Us message has been successfully sent.")
  printf("\n**** TOMS END")
end

控制器中的两个 printf 实际上打印了它们的消息,但 joe() 中的一个从不打印。没有错误或任何东西。

如果我在文件 user_tommail.rb 中破坏 joe() 说 joe(),我会得到一个错误,指出找不到该函数,所以我知道控制器知道它。

我做错了什么?

您应该调用 deliver_now 来触发邮件程序发送电子邮件:

UserTommail.joe.deliver_now

See the full list of available methods in docs.

给Rails 4 发送一封邮件

UserTommail.joe.deliver_now

UserTommail.joe.deliver_later #Enqueues the email to be delivered through Active Job. When the job runs it will send the email using deliver_now.

给Rails3 发一封邮件

UserTommail.joe.deliver

这里的问题是 ActionMailer 试图 "clever" 它所做的事情,并且在需要其 return 值之前不会真正调用您的邮件程序方法。

您的邮件程序方法 joe 将 return 一个 ActionMailer::MessageDelivery 对象,它包装了一个 Mail::Message 对象(即使您没有明确表示要发送一个电子邮件)。 Mail::Message 被延迟计算,这意味着它不会被实例化(并且您的方法不会被调用)直到需要它。

强制评估的一种方法是尝试发送带有 deliver_nowdeliver_later 的 returned 电子邮件,但另一种方法是简单地检查邮件。

如果你有 my_email = UserTommail.joe() 然后调用 my_email.message,它会强制方法为 运行,你会在控制台中看到你的 printf