Wie verwende ich meine Ansichtshilfen in meinen ActionMailer-Ansichten?

227

Ich möchte die Methoden verwenden, die ich app/helpers/annotations_helper.rbin meinen ReportMailer-Ansichten ( app/views/report_mailer/usage_report.text.html.erb) definiert habe. Wie mache ich das?

Basierend auf diesem Handbuch scheint die add_template_helper(helper_module)Methode das zu tun, was ich will, aber ich kann nicht herausfinden, wie ich sie verwenden soll.

(Übrigens, gibt es einen Grund, warum Sie in Maileransichten Zugriff auf eine andere Gruppe von Helfern erhalten? Das ist ziemlich ärgerlich.)

Tom Lehman
quelle

Antworten:

324

In der Mailer-Klasse, mit der Sie Ihre E-Mails verwalten:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end
Mark Connell
quelle
4
Funktioniert in diesem Fall nicht für mich (Rails 3.2.8): Ich habe eine Methode in ApplicationController definiert und mache sie zu einem Helfer von helper_method: my_helper_wannabe, aber die Methode "my_helper_wannabe" wird im Mailer nicht verfügbar.
Giang Nguyen
Siehe Dukes Antwort unten für den Umgang mit Rails 3.
Chris Peters
Arbeiten in Rails 3.2.11
Jan
1
Ich dachte, diese sollten automatisch in Rails 4 enthalten sein? guides.rubyonrails.org/…
gabeodess
6
Dies ist eine alte Antwort, aber nur zu sagen, dass dies in Rails 5.2
Archonic
158

Verwenden Sie in Rails 3 einfach die Hilfsmethode oben in Ihrer ActionMailer-Klasse:

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

Ich habe gerade einen Block übergeben, da ich ihn nur in dem einen Mailer brauche:

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

(Stellen Sie sicher, dass Sie config.action_mailer.default_url_options festlegen.)

(und wenn Sie url_for verwenden, müssen Sie Folgendes übergeben: only_path => false)

Herzog
quelle
3
Dies funktioniert, es ist jedoch empfehlenswert, bereits in ApplicationController definierte Helfer auch für einzelne ActionMailer-Klassen neu anzugeben. ActionMailer erweitert ActionController so, dass sie aus einer gemeinsamen Hierarchie stammen. Mehr ein Kommentar zu Rails als zu Ihrer Lösung ...
robbie613
3
Und wenn sich der Helfer in einem Namespace befindet, können Sie dies tunhelper :'namespace/mail'
Jonathon Batson
Wenn sich der Helfer in einem Namespace befindet, akzeptiert er auch nur eine Zeichenfolge (anstelle eines Symbols)helper 'namespace/mail'
Pwnrar
2
Funktioniert auf Schienen 5.2!
RousseauAlexandre
28

Für alle Mailer in Rails 3 (Einstellung "Anwendungs" -Helfer):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end
Edison Machado
quelle
Die beste Antwort für geteilte E-Mail-Partials. Vielen Dank!
Alexey Shein
2
NICHT wahr - helper :applicationfunktioniert gut in Rails 4.2.1.
Steakchaser
Funktioniert auch für eigene E-Mail-Vorlagen für devise. helper :applicationfunktioniert in diesem Fall nicht.
Sven R.
1
funktioniert nicht für 4.2.5.1 - include ApplicationHelperhat funktioniert
daslicious
23

Für Ruby on Rails 4 musste ich zwei Dinge tun:

(1) Wie Duke bereits sagte, wenn der Helfer, den Sie hinzufügen möchten, UsersHelperbeispielsweise ist, fügen Sie hinzu

helper :users

zur abgeleiteten ActionMailerKlasse (zB app/mailers/user_mailer.rb)

(2) Danach habe ich einen neuen Fehler erhalten:

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

Um dies zu beheben, fügen Sie die Zeile hinzu

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

zu jeder der config/environments/*.rbDateien. Für config/environments/production.rbErsetzen localhostdurch einen besser geeigneten Wirt für die Produktion Helfer generierten URLs.


F: Warum benötigt die E-Mail-Ansicht für # 2 diese Informationen und die regulären Ansichten nicht?

A: Da die regulären Ansichten das nicht kennen müssen host, werden alle generierten Links von dem Host bereitgestellt, auf den sie verlinken. Links, die in E-Mails angezeigt werden, werden nicht vom selben Host bereitgestellt (es sei denn, Sie verlinken auf hotmail.comoder gmail.comusw.).

Matt
quelle
Was ist mit komponierten Namen? User::ComposedHelper
Cyril Duchon-Doris
19

Sie können einfach Ihren Mailer hinzufügen

helper :application

oder was auch immer du brauchst

user1136228
quelle
4
Dies ist ein Duplikat einer früheren Antwort - @Shevaun
robbie613
1
Funktioniert auf Schienen 5.2!
RousseauAlexandre
17

(Dies ist eine alte Frage, aber Rails hat sich weiterentwickelt, sodass ich teile, was in Rails 5.2 für mich funktioniert.)

In der Regel möchten Sie beim Rendern der Betreffzeile einer E-Mail sowie des HTML-Codes einen benutzerdefinierten Ansichtshelfer verwenden. In dem Fall, in dem sich der Ansichtshelfer in app / helpers / application_helper.rb befindet, gehen Sie wie folgt vor:

module ApplicationHelper

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

end

Ich kann eine dynamische Betreffzeile und Vorlage für E-Mails erstellen, die beide den Helfer verwenden, aber ich muss Rails anweisen, den ApplicationHelper explizit in apps / mailer / user_mailer.rb auf zwei verschiedene Arten zu verwenden, wie Sie in der zweiten und dritten Zeile hier sehen können ::

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: '[email protected]',
    subject: "Thanks for coming on #{mydate(@party.created_at, @party.timezone)}")
  end

end

Ich sollte erwähnen, dass diese beiden Zeilen genauso gut funktionieren, also wählen Sie die eine oder andere:

helper :application

add_template_helper(ApplicationHelper)

FWIW, die E-Mail-Vorlage unter app / views / user_mailer / party_thanks.html.erb sieht folgendermaßen aus:

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

Und der Controller app / controller / party_controller.rb sieht so aus

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

Ich muss OP (@Tom Lehman) und @gabeodess zustimmen, dass sich das alles unter https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers ziemlich verworren anfühlt. Vielleicht fehlt mir etwas. .

MSC
quelle
5

In meinem Fall für Rails4 gefällt mir Folgendes:

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

und

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

damit Sie nicht add_template_helperüberall angeben müssen .

Yoshi
quelle