【问题标题】:How to use my view helpers in my ActionMailer views?如何在我的 ActionMailer 视图中使用我的视图助手?
【发布时间】:2009-09-13 06:02:34
【问题描述】:

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

基于this guideadd_template_helper(helper_module) 方法似乎可以满足我的需求,但我不知道如何使用它。

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

【问题讨论】:

标签: ruby-on-rails


【解决方案1】:

在您用来管理电子邮件的邮件程序类中:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

【讨论】:

  • 在这种情况下对我不起作用(Rails 3.2.8):我在 ApplicationController 中定义了一个方法,并通过 helper_method 使其成为助手:my_helper_wannabe,但方法“my_helper_wannabe”没有在邮件程序中可用。
  • 我认为这些应该自动包含在 Rails 4 中? guides.rubyonrails.org/…
  • 这是一个古老的答案,但只是插话说这在 Rails 5.2 中有效
  • 这终于在 Rails 6.1.0.rc1 中中断了?
  • 这在 6.1 中不起作用。对于 Rails 6.1,请使用 Duke 的以下答案:stackoverflow.com/questions/1416978/…helper :helpername
【解决方案2】:

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

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)

【讨论】:

  • 这行得通,但感觉将 ApplicationController 中已经定义的帮助器也重新指定为单个 ActionMailer 类是不合适的。 ActionMailer 扩展了 ActionController,因此它们来自一个共同的层次结构。更多关于 Rails 的评论比您的解决方案...
  • 如果助手在命名空间中,你可以这样做helper :'namespace/mail'
  • 如果助手在命名空间中,它也只接受一个字符串(而不是一个符号)helper 'namespace/mail'
  • 在 Rails 5.2 上工作!
  • 当 ActionMailer 类被埋在一个 gem 中时,你如何做到这一点,比如 Devise?将&lt;% helper :mail %&gt; 放在邮件视图顶部会失败,并显示undefined method 'helper'。理想情况下,有一种方法可以为 all Action Mailer 邮件设置helper :mail……
【解决方案3】:

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

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

【讨论】:

  • 共享电子邮件部分的最佳答案。谢谢!
  • 不正确 - helper :application 在 Rails 4.2.1 中工作正常。
  • 即使对于 devise 自己的电子邮件模板也能正常工作。 helper :application 在这种情况下不起作用。
  • 不适用于 4.2.5.1 -- include ApplicationHelper 确实有效
【解决方案4】:

对于 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,为什么邮件视图需要这些信息,而常规视图不需要?

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

【讨论】:

  • 组合名称怎么样? User::ComposedHelper
【解决方案5】:

(这是一个老问题,但 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,这一切都让人感到非常复杂,所以也许我遗漏了什么......

【讨论】:

    【解决方案6】:

    你可以在你的邮件中添加

    helper :application
    

    或任何你需要的助手

    【讨论】:

    • 这是之前回复的副本 - @Shevaun
    • 在 Rails 5.2 上工作!
    • 在 Rails 6.0 中工作
    • 在 Rails 6.1.1 中为我工作。
    【解决方案7】:

    就我的 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

    【讨论】:

      【解决方案8】:

      这就是我在 Rails 6 中所做的

      class ApplicationMailer < ActionMailer::Base
        default from: 'community@example.com'
        layout 'mailer'
      
        # Add whatever helper you want
        helper :application  
      
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-10
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        相关资源
        最近更新 更多