format.html如何知道要渲染的内容?

时间:2013-05-19 15:31:34

标签: ruby-on-rails

我在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

2 个答案:

答案 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

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