我在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
答案 0 :(得分:1)
你是对的,ActionMailer不是一个控制器(那是ActionController)。 ActionController的respond_to
方法和ActionMailer的mail
方法完全不同,但它们都有“我们应该发送什么样的响应”的概念,所以rails devs选择提供一个两种格式选择的类似界面。
在ActionController中,respond_to
方法接受一个块并使用HTTP请求环境来选择要呈现的格式。
在ActionMailer中,mail
使用一个块并使用不同的逻辑来决定要呈现的格式。当您提供format.html
时,它只会在您的视图文件夹中查找包含<method_name>.<format>.<acceptable_template_type>
的模板,例如SIGNUP_NOTIFICATION.html.erb。顺便说一句,您应该在snake_case(signup_notification)中命名所有方法。大写方法名称是非惯用的,可能会导致问题。
技术说明
虽然你不需要知道这个使用ActionMailer,但我认为通过这里的模板生成工作流程是有趣的。它包括一些有趣的元编程,但逻辑比常规控制器(没有HTTP环境)更简单。
您可以在source for mail中看到它调用a function to render the messages。如果您给mail
一个块,则邮件会创建一个ActionMailer::Collector实例(包括AbstractController :: Collector)并生成此收集器。因此,在您的示例中,收集器获取调用它的函数html
(因为您的do |format| ... end
有一个参数,format
将是调用yield(collector)
时的收集器实例{{ 3}}
所以ActionMailer :: Collector的一个实例被传递到你的do |format| ...
块,其中有一个函数html
,收集器使用here
来自AbstractController :: Collector,以便它可以响应任何mime类型,将请求的类型传递给ActionMailler::Collector#custom
,它实际构建电子邮件,方法是在views文件夹中查找与该类型匹配的模板。
答案 1 :(得分:0)
Mailer就像一个控制器,但没有继承ActionController,对于你的邮件程序,你会把你的视图放在app/views/user_mailer/SIGNUP_NOTIFICATION.html.erb
您可以发送此电子邮件,在您的邮件程序中调用该方法:
UserMailer.SIGNUP_NOTIFICATION(some_user_instance).deliver
我不确定这是否是你所要求的。