Come utilizzare i miei helper di visualizzazione nelle visualizzazioni di ActionMailer?


227

Voglio usare i metodi che ho definito in app/helpers/annotations_helper.rb nelle mie viste ReportMailer ( app/views/report_mailer/usage_report.text.html.erb). Come faccio a fare questo?

Sulla base di questa guida sembra che iladd_template_helper(helper_module) metodo possa fare quello che voglio, ma non riesco a capire come usarlo.

(A proposito, c'è un motivo per cui hai accesso a un diverso set di helper nelle visualizzazioni di mailer? Questo è piuttosto fastidioso.)


Risposte:


324

Nella classe mailer che stai utilizzando per gestire le tue e-mail:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

4
In questo caso non funziona per me (Rails 3.2.8): ho un metodo definito in ApplicationController e lo faccio diventare un aiuto di helper_method: my_helper_wannabe, ma il metodo "my_helper_wannabe" non diventa disponibile in mailer.
Giang Nguyen il

Vedi la risposta di Duke di seguito per come gestire Rails 3.
Chris Peters,

Lavori in Rails 3.2.11
Gen

1
Pensavo che dovessero essere automaticamente inclusi in Rails 4? guide.rubyonrails.org/…
gabeodess,

6
Questa è una risposta antica, ma basta intervenire per dire che ha funzionato in Rails 5.2
Archonic,

158

In Rails 3, basta usare il metodo helper nella parte superiore della classe ActionMailer:

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

Sono appena passato in un blocco, dato che ne ho solo bisogno nell'unico Mailer:

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

(assicurati di impostare config.action_mailer.default_url_options.)

(e se usi url_for, assicurati di passare: only_path => false)


3
Funziona, ma mi sento ansioso di specificare nuovamente gli helper già definiti in ApplicationController anche per le singole classi ActionMailer. ActionMailer estende ActionController in modo che provengano da una gerarchia comune. Più di un commento su Rails che della tua soluzione ...
robbie613,

3
E se l'aiutante si trova in uno spazio dei nomi, puoi farlohelper :'namespace/mail'
Jonathon Batson,

se l'helper si trova in uno spazio dei nomi accetta anche solo una stringa (anziché un simbolo)helper 'namespace/mail'
Pwnrar

2
Funziona su Rails 5.2!
RousseauAlexandre,

28

Per tutti i mailer in Rails 3 (impostazione dell'helper "applicazione"):

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

La migliore risposta per le email parziali condivise. Grazie!
Alexey Shein,

2
NON vero - helper :applicationfunziona bene in Rails 4.2.1.
steakchaser,

Funziona bene anche per i propri modelli di email per devise. helper :applicationnon funziona in questo caso.
Sven R.,

1
non funzionava per 4.2.5.1 - include ApplicationHelperfunzionava
insicuro il

23

Per Ruby on Rails 4, ho dovuto fare 2 cose:

(1) Come duca già detto da , se l'helper che vuoi aggiungere è UsersHelperper esempio, allora aggiungi

helper :users

alla ActionMailerclasse derivata (ad es. app/mailers/user_mailer.rb)

(2) Successivamente, ho ricevuto un nuovo errore:

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

Per risolvere questo problema, aggiungi la riga

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

a ciascuno dei config/environments/*.rbfile. Perconfig/environments/production.rb sostituire localhostcon un ospite più appropriato per gli URL helper generati produzione.


D: Per # 2, perché la vista di posta elettronica ha bisogno di queste informazioni e le viste normali no?

A: Perché le viste normali non hanno bisogno di conoscere il host, dal momento che tutti i collegamenti generati sono offerti dall'host a cui si collegano. I link che appaiono nelle e-mail non sono serviti dallo stesso ospite (a meno che non stai facendo riferimento hotmail.como gmail.com, ecc)


E i nomi composti? User::ComposedHelper
Cyril Duchon-Doris,


17

(Questa è una vecchia domanda ma Rails si è evoluto, quindi sto condividendo ciò che funziona per me in Rails 5.2.)

In genere potresti voler utilizzare un helper di visualizzazione personalizzato per il rendering della riga dell'oggetto di un'e-mail e dell'HTML. Nel caso in cui l'helper della vista sia in app / helpers / application_helper.rb come segue:

module ApplicationHelper

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

end

Posso creare un oggetto e un modello dinamici di posta elettronica che utilizzano entrambi l'helper ma devo dire a Rails di usare esplicitamente ApplicationHelper in apps / mailer / user_mailer.rb in due modi diversi, come puoi vedere nella seconda e terza riga qui :

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

Devo dire che queste due linee funzionano altrettanto bene, quindi scegli l'una o l'altra:

helper :application

add_template_helper(ApplicationHelper)

FWIW, il modello e-mail su app / views / user_mailer / party_thanks.html.erb è simile al seguente:

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

E il controller app / controller / party_controller.rb si presenta così

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

Sono d'accordo con OP (@Tom Lehman) e @gabeodess che tutto ciò sembra abbastanza contorto dato https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers, quindi forse mi manca qualcosa .. .


5

nel mio caso per Rails4, mi piace questo:

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

e

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

in modo da non dover specificare add_template_helperovunque.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.