Jak korzystać z pomocników widoku w widokach ActionMailer?

227

Chcę użyć metod, które zdefiniowałem app/helpers/annotations_helper.rbw moich widokach ReportMailer ( app/views/report_mailer/usage_report.text.html.erb). Jak mam to zrobic?

Na podstawie tego przewodnika wydaje się, że add_template_helper(helper_module)metoda może robić to, co chcę, ale nie mogę wymyślić, jak jej użyć.

(BTW, czy istnieje powód, dla którego masz dostęp do innego zestawu pomocników w widokach mailera? To dość denerwujące).

Tom Lehman
źródło

Odpowiedzi:

324

W klasie mailera używanej do zarządzania wiadomościami e-mail:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end
Mark Connell
źródło
4
W tym przypadku nie działa dla mnie (Railsy 3.2.8): Mam metodę zdefiniowaną w ApplicationController i zmieniam ją w helper_method: my_helper_wannabe, ale metoda „my_helper_wannabe” nie jest dostępna w mailerze.
Giang Nguyen,
Zobacz odpowiedź Duke'a poniżej, jak poradzić sobie w Rails 3.
Chris Peters
Pracuje w Rails 3.2.11
sty
1
Myślałem, że powinny one zostać automatycznie uwzględnione w Rails 4? guide.rubyonrails.org/…
gabeodess
6
To starożytna odpowiedź, ale po prostu wtrąca się, by powiedzieć, że zadziałało w Rails 5.2
Archonic
158

W Rails 3 wystarczy użyć metody helper na szczycie klasy ActionMailer:

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

Właśnie przeszedłem blok, ponieważ potrzebuję go tylko w jednym Mailerze:

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

(pamiętaj, aby ustawić config.action_mailer.default_url_options.)

(a jeśli używasz adresu url_for, pamiętaj, aby podać: only_path => false)

Książę
źródło
3
Działa to, ale czuje się dobrze, gdy ponownie określa pomocników zdefiniowanych już w ApplicationController do poszczególnych klas ActionMailer. ActionMailer rozszerza ActionController, aby pochodziły ze wspólnej hierarchii. Więcej komentarza na temat Railsów niż twojego rozwiązania ...
robbie613
3
A jeśli pomocnik znajduje się w przestrzeni nazw, możesz to zrobićhelper :'namespace/mail'
Jonathon Batson,
jeśli pomocnik znajduje się w przestrzeni nazw, akceptuje także tylko ciąg znaków (zamiast symbolu)helper 'namespace/mail'
Pwnrar,
2
Działa na Railsach 5.2!
RousseauAlexandre
28

Dla wszystkich mailerów w Rails 3 (ustawienie pomocnika „aplikacji”):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end
Edison Machado
źródło
Najlepsza odpowiedź na udostępnione częściowe wiadomości e-mail. Dzięki!
Alexey Shein
2
NIE prawda - helper :applicationdziała dobrze w Railsach 4.2.1.
steakchaser
Działa dobrze nawet dla własnych szablonów e-mail dla devise. helper :applicationw tym przypadku nie działa.
Sven R.,
1
nie działa dla 4.2.5.1 - include ApplicationHelperdziałało
trudne
23

W przypadku Ruby on Rails 4 musiałem zrobić 2 rzeczy:

(1) As już powiedział Duke , jeśli na przykład pomocnikiem, którego chcesz dodać UsersHelper, to dodaj

helper :users

do ActionMailerklasy pochodnej (npapp/mailers/user_mailer.rb )

(2) Następnie otrzymałem nowy błąd:

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

Aby to naprawić, dodaj linię

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

do każdego z config/environments/*.rbplików. Dlaconfig/environments/production.rb zastąpienia localhostbardziej odpowiednim hostem dla adresów URL generowanych przez pomocników produkcyjnych.


P: W przypadku nr 2, dlaczego widok poczty potrzebuje tych informacji, a zwykłe widoki nie?

Odp .: Ponieważ zwykłe widoki nie muszą znać host, ponieważ wszystkie wygenerowane linki są obsługiwane z hosta, do którego prowadzą. Łącza wyświetlane w wiadomościach e-mail nie są udostępniane z tego samego hosta (chyba że łączysz się z hotmail.comlub gmail.comitd.)

Matt
źródło
A co z nazwami złożonymi? User::ComposedHelper
Cyril Duchon-Doris
20

Możesz po prostu dodać w swoim mailerze

helper :application

lub cokolwiek potrzebujesz pomocnika

użytkownik1136228
źródło
4
jest to duplikat wcześniejszej odpowiedzi - @Shevaun
robbie613
1
Działa na Railsach 5.2!
RousseauAlexandre
17

(To stare pytanie, ale Railsy ewoluowały, dlatego dzielę się tym, co działa dla mnie w Railsach 5.2.)

Zazwyczaj możesz użyć niestandardowego pomocnika widoku do renderowania tematu wiadomości e-mail, a także HTML. W przypadku, gdy pomocnik widoku znajduje się w app / helpers / application_helper.rb w następujący sposób:

module ApplicationHelper

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

end

Mogę utworzyć dynamiczny wiersz tematu i szablon, które używają pomocnika, ale muszę powiedzieć Railsom, aby korzystały z ApplicationHelper jawnie w apps / mailer / user_mailer.rb na dwa różne sposoby, jak widać w drugim i trzecim wierszu tutaj :

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

Powinienem wspomnieć, że te dwie linie działają równie dobrze, więc wybierz jedną lub drugą:

helper :application

add_template_helper(ApplicationHelper)

FWIW, szablon e-maila na app / views / user_mailer / party_thanks.html.erb wygląda następująco:

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

A kontroler app / controller / party_controller.rb wygląda następująco

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

Muszę zgodzić się z OP (@Tom Lehman) i @gabeodess, że to wszystko wydaje się dość skomplikowane, biorąc pod uwagę https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers, więc może coś mi brakuje ... .

MSC
źródło
5

w moim przypadku dla Rails4 lubię to:

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

i

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

abyś nie musiał określać add_template_helperwszędzie.

Yoshi
źródło