ActionMailer如何将本地变量传递到erb模板中

17

我知道我可以定义实例变量,例如:

def user_register(username, email)
  @username = username
  @email = email

  mail(:to => email, :subject => "Welcome!", :template_name => "reg_#{I18n.locale}")
end

但是,是否有一种方法可以使用本地变量,就像将:locals传递给partials一样?

4个回答

29
正如ronalchn所指出的那样,有:locals的是render而不是mail方法。因此,您需要直接访问render方法以传递局部变量。
您可以给mail提供一个块,这样就可以访问render方法,类似于这样:
mail(to: "your_mail@example.com", subject: "Test passing locals to view from mailer") do |format|
  format.html {
    render locals: { recipient_name: "John D." }
  }
end

现在,您应该能够使用"Hello <%= recipient_name %>"了。


谢谢,@rap1ds 我会尝试那种方法 :) - Dmitri

11
所有可用于`mail`方法的选项都可以在http://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-mail找到。
我们知道`render`有一个`:locals`选项。然而,我们可以看到`mail`没有可用的`:locals`选项。因此,除非你想使用丑陋的全局变量或持久化数据库对象(不要这样做),否则没有比使用实例变量更好的方式。
实例变量是你应该使用的内容。

好的。谢谢!那我就会使用它们了! - Dmitri

4
在Rails 5中,你只需要在方法中使用@来定义实例变量。你不再能够使用locals属性来达到此目的。
class UserMailer < ApplicationMailer

  def welcome_email(user_id:, to_email:, user_full_name:, token:)    
    # Mail template variables
    @user = User.find_by(id: user_id)
    @token = token

    mail(:to => to_email,
       :subject => MAILER_SUBJECTS_WELCOME,
       :template_path => "user_mailer",
       :template_name => "welcome_email")
  end
end

然后您只需在电子邮件模板中使用<%= @user %><%= @token %>即可访问它们。


7
即使在Rails 5之前,这种情况也一直存在。 - Leo Lei

-1

你实际上可以在邮件中使用locals选项,只是有点混乱和不一致。

一旦你使用了:locals,你就可以在邮件模板中通过实例变量访问这些locals,例如:

:locals => { :name => 'Jane' }

然后在模板中

Dear <%= @name %>,

当然!虽然这可能已经在Rails 2上进行了测试,但自那时以来可能会有所改变。 - Jai
1
这在Rails 4.2中不起作用。根据其他答案,我也不会指望它能起作用。 - Tyler Collier
最好在答案中说明这适用于哪个版本的Rails。 - sdeburca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接