0

我在文件 app/mailers/user_mailer.rb 中有以下代码。现在 format.html 如何知道要渲染什么。它不在任何控制器的操作中。我了解它默认呈现显示视图的基本事实,但这里没有控制器没有操作。它仍然如何工作?

class UserMailer < ActionMailer::Base
  def SIGNUP_NOTIFICATION(user)
    @recipients = "#{user.email}"
    @from = "#{sender.email}"
    mailer_name = "SIGNUP_NOTIFICATION"
    mail(:to => @recipients, :from => @from) do |format|
      format.html
    end
  end
4

2 回答 2

1

没错,ActionMailer 不是控制器(即 ActionController)。respond_toActionController 的方法mail和 ActionMailer 的方法是完全不同的东西,但是它们都有“我们应该发送什么样的响应”的概念,因此 Rails 开发人员选择在两者中提供类似的接口来选择格式。

在 ActionController 中,该respond_to方法采用一个块并使用 HTTP 请求环境来选择要呈现的格式。

在 ActionMailer 中,mail接受一个块并使用不同的逻辑来决定要呈现哪种格式。当您提供它时,format.html它只是在您的视图文件夹中查找带有 的模板<method_name>.<format>.<acceptable_template_type>,例如 SIGNUP_NOTIFICATION.html.erb。顺便说一句,您应该在 snake_case (signup_notification) 中命名所有方法。大写的方法名称是非惯用的,可能会导致问题。

技术说明

虽然您不需要知道这一点来使用 ActionMailer,但我认为在这里了解模板生成的工作流程是很有趣的。它包括一些有趣的元编程,但逻辑比常规控制器更简单(没有 HTTP 环境)。

您可以在邮件源中看到它调用了一个函数来呈现消息。如果你给了一个块,邮件会创建一个ActionMailer::Collectormail的实例(包括 AbstractController::Collector)并让给这个收集器。因此,在您的示例中,收集器获取在其上调用的函数(因为您有一个参数,所以在此处调用时将成为收集器实例。htmldo |format| ... endformatyield(collector)

因此,ActionMailer::Collector 的实例被传递到您的do |format| ...块中,在那里它html调用了函数,收集器使用来自 AbstractController::Collector 的方法缺失技巧 ,以便它可以响应任何 mime 类型,将请求的类型传递给ActionMailler::Collector#custom它实际上是通过在视图文件夹中查找与该类型匹配的模板来构建电子邮件的。

于 2013-05-19T16:00:07.287 回答
0

Mailer 就像一个控制器,但没有继承 ActionController,对于您的邮件程序,您可以将您的视图放入app/views/user_mailer/SIGNUP_NOTIFICATION.html.erb

您可以在邮件程序中调用该方法发送此电子邮件:

UserMailer.SIGNUP_NOTIFICATION(some_user_instance).deliver

我不确定这是否是您所要求的。

于 2013-05-19T16:01:53.303 回答