没错,ActionMailer 不是控制器(即 ActionController)。respond_to
ActionController 的方法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)并让给这个收集器。因此,在您的示例中,收集器获取在其上调用的函数(因为您有一个参数,所以在此处调用时将成为收集器实例。html
do |format| ... end
format
yield(collector)
因此,ActionMailer::Collector 的实例被传递到您的do |format| ...
块中,在那里它html
调用了函数,收集器使用来自 AbstractController::Collector 的方法缺失技巧
,以便它可以响应任何 mime 类型,将请求的类型传递给ActionMailler::Collector#custom
它实际上是通过在视图文件夹中查找与该类型匹配的模板来构建电子邮件的。