如何在ActionMailer视图中使用视图帮助器?


227

我想使用app/helpers/annotations_helper.rb在ReportMailer视图(app/views/report_mailer/usage_report.text.html.erb)中定义的方法。我该怎么做呢?

根据本指南,该add_template_helper(helper_module)方法似乎可以满足我的要求,但我不知道如何使用它。

(顺便说一句,您是否有理由在邮件视图中访问另一组帮助者?这很烦人。)


Answers:


324

在用于管理电子邮件的mailer类中:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

4
在这种情况下对我不起作用(Rails 3.2.8):我在ApplicationController中定义了一个方法,并通过helper_method:my_helper_wannabe使其成为助手,但是方法“ my_helper_wannabe”在邮件程序中不可用。
Giang Nguyen

见公爵的回答下面如何在Rails的3.处理
克里斯·彼得斯

在Rails 3.2.11中工作
1

1
我认为这些应该自动包含在Rails 4中吗? guides.rubyonrails.org/…– gabeodess
2015年

6
这是一个古老的答案,但只是插话说这个工作对Rails 5.2
Archonic

158

在Rails 3中,只需使用ActionMailer类顶部的helper方法:

helper :mail   # loads app/helpers/mail_helper.rb & includes MailHelper

我只是传递了一个代码块,因为我只需要在一个Mailer中使用它:

helper do
  def host_url_for(url_path)
    root_url.chop + url_path
  end
end

(请务必设置config.action_mailer.default_url_options。)

(如果您使用url_for,请确保传递:only_path => false)


3
这可行,但是对于将ApplicationController中已经定义的帮助程序重新指定给各个ActionMailer类也感到很尴尬。ActionMailer扩展了ActionController,因此它们来自共同的层次结构。关于Rails的评论多于您的解决方案……
robbie613

3
如果帮助程序在名称空间中,则可以执行helper :'namespace/mail'
Jonathon Batson 2014年

如果帮助程序位于命名空间中,则它也仅接受字符串(而不是符号)helper 'namespace/mail'
Pwnrar

2
在Rails 5.2上工作!
RousseauAlexandre

28

对于Rails 3中的所有邮件(设置“应用程序”帮助程序):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end

共享电子邮件的最佳答案。谢谢!
Alexey Shein 2014年

2
不正确- helper :application在Rails 4.2.1中工作正常。
牛排追逐者,2015年

即使对于自己的电子邮件模板也可以正常工作devisehelper :application在这种情况下不起作用。
Sven R.

1
对于4.2.5.1 include ApplicationHelper不起作用– 确实起作用
令人讨厌的2016年

23

对于Ruby on Rails 4,我必须做两件事:

(1)如Duke所说,UsersHelper例如,如果要添加的帮助程序,则添加

helper :users

到派生ActionMailer类(例如app/mailers/user_mailer.rb

(2)之后,我得到了一个新错误:

ActionView::Template::Error (Missing host to link to! Please provide the :host
parameter, set default_url_options[:host], or set :only_path to true)

要解决此问题,请添加以下行

config.action_mailer.default_url_options = { :host => 'localhost' }

到每个config/environments/*.rb文件。对于config/environments/production.rb,替换localhost为生产助手生成的URL的更合适的主机。


问:对于#2,为什么邮件视图需要此信息,而常规视图则不需要?

答:因为常规视图不需要了解host,因为所有生成的链接都是从它们链接到的主机提供的。电子邮件中显示的链接不是由同一主机提供的(除非您链接到hotmail.comgmail.com,等等)


组合名称呢?User::ComposedHelper
西里尔·杜尚-多丽丝


17

(这是一个古老的问题,但是Rails不断发展,因此我将分享在Rails 5.2中对我有用的东西。)

通常,您可能需要使用自定义视图帮助器来呈现电子邮件和HTML的主题行。如果视图帮助程序位于app / helpers / application_helper.rb中,则如下所示:

module ApplicationHelper

  def mydate(time, timezone)
    time.in_time_zone(timezone).strftime("%A %-d %B %Y")
  end

end

我可以创建一个都使用助手的动态电子邮件主题行和模板,但是我需要告诉Rails以两种不同的方式在apps / mailer / user_mailer.rb中显式使用ApplicationHelper ,如您在此处的第二和第三行中所见:

class UserMailer < ApplicationMailer

  include ApplicationHelper  # This enables me to use mydate in the subject line
  helper :application  # This enables me to use mydate in the email template (party_thanks.html.erb)

  def party_thanks
    @party = params[:party]
    mail(to: 'user@domain.com',
    subject: "Thanks for coming on #{mydate(@party.created_at, @party.timezone)}")
  end

end

我应该指出,这两行效果很好,因此请选择其中之一:

helper :application

add_template_helper(ApplicationHelper)

FWIW,位于app / views / user_mailer / party_thanks.html.erb的电子邮件模板如下所示:

<p>
  Thanks for coming on <%= mydate(@party.created_at, @party.timezone) %>
</p>

并且app / controller / party_controller.rb控制器看起来像这样

class PartyController < ApplicationController
  ...
  def create
    ...
    UserMailer.with(party: @party).party_thanks.deliver_later
    ...
  end
end

我必须同意OP(@Tom Lehman)和@gabeodess的观点,鉴于https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers,这一切都让人感到费解,所以也许我错过了一些东西。 。


5

就Rails4而言,我确实是这样的:

# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  add_template_helper ApplicationHelper
  ...
end

# app/mailers/user_mailer.rb
class AccountMailer < ApplicationMailer
  def some_method(x, y)
  end
end

这样您就不必在add_template_helper所有地方都指定。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.