Como usar meus assistentes de exibição nas minhas visualizações do ActionMailer?

227

Eu quero usar os métodos definidos app/helpers/annotations_helper.rbem meus modos de exibição ReportMailer (app/views/report_mailer/usage_report.text.html.erb ). Como eu faço isso?

Com base neste guia , parece que oadd_template_helper(helper_module) método pode fazer o que eu quero, mas não consigo descobrir como usá-lo.

(BTW, existe uma razão para você ter acesso a um conjunto diferente de ajudantes nas visualizações de mala direta? Isso é bastante irritante.)

Tom Lehman
fonte
semelhante - amolnpujari.wordpress.com/2013/12/27/…
Amol Pujari

Respostas:

324

Na classe de mala direta que você está usando para gerenciar seus emails:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end
Mark Connell
fonte
4
Neste caso, não funciona para mim (Rails 3.2.8): tenho um método definido no ApplicationController e o ajudo por helper_method: my_helper_wannabe, mas o método "my_helper_wannabe" não fica disponível no mailer.
Giang Nguyen
Veja a resposta de Duke abaixo para saber como lidar com o Rails 3. #
Chris Peters
Funciona no Rails 3.2.11
Jan
1
Eu pensei que eles deveriam ser incluídos automaticamente no Rails 4? guias.rubyonrails.org/…
gabeodess
6
Esta é uma resposta antiga, mas apenas para dizer que isso funcionou no Rails 5.2
Archonic 10/11/18
158

No Rails 3, basta usar o método helper na parte superior da sua classe ActionMailer:

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

Acabei de passar em um bloco, já que só preciso dele no Mailer:

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

(certifique-se de definir config.action_mailer.default_url_options.)

(e se você usar url_for, não deixe de passar: only_path => false)

Duque
fonte
3
Isso funciona, mas parece estranho especificar novamente os auxiliares já definidos no ApplicationController para classes individuais do ActionMailer. O ActionMailer estende o ActionController para que eles venham de uma hierarquia comum. Mais de um comentário on Rails do que a sua solução ...
robbie613
3
E se o auxiliar é em um espaço que você pode fazerhelper :'namespace/mail'
Jonathon Batson
se o ajudante está em um namespace também aceita apenas uma seqüência (em vez de um símbolo)helper 'namespace/mail'
Pwnrar
2
Funciona no Rails 5.2!
RousseauAlexandre
28

Para todas as malas diretas no Rails 3 (configurando o auxiliar "aplicativo"):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end
Edison Machado
fonte
A melhor resposta para parciais de email compartilhados. Obrigado!
Alexey Shein
2
NÃO é verdade - helper :applicationfunciona bem no Rails 4.2.1.
steakchaser
Funciona bem mesmo para modelos de email próprios para devise. helper :applicationnão funciona neste caso.
Sven R.
1
não trabalhando para 4.2.5.1 - include ApplicationHelperfez o trabalho
daslicious
23

Para Ruby on Rails 4, eu tinha que fazer duas coisas:

(1) Como Duke já disse, se o ajudante que você deseja adicionar for, UsersHelperpor exemplo, adicione

helper :users

para a ActionMailerclasse derivada (por exemplo app/mailers/user_mailer.rb)

(2) Depois disso, recebi um novo erro:

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

Para corrigir isso, adicione a linha

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

para cada um dos config/environments/*.rbarquivos. Para config/environments/production.rb, substitua localhostpor um host mais apropriado para os URLs gerados pelo auxiliar de produção.


P: Para o número 2, por que a exibição de email precisa dessas informações e as exibições regulares não?

R: Como as visualizações regulares não precisam conhecer host, uma vez que todos os links gerados são veiculados a partir do host ao qual estão vinculados. Links que aparecem em e-mails não são servidos a partir do mesmo host (a menos que você está ligando hotmail.comou gmail.com, etc.)

Matt
fonte
E os nomes compostos? User::ComposedHelper
Cyril Duchon-Doris
20

Você pode apenas adicionar na sua mala direta

helper :application

ou qualquer ajudante que você precisa

user1136228
fonte
4
esta é uma duplicata de uma resposta anterior - @Shevaun
robbie613
1
Funciona no Rails 5.2!
RousseauAlexandre
17

(Essa é uma pergunta antiga, mas o Rails evoluiu, então estou compartilhando o que funciona para mim no Rails 5.2.)

Normalmente, você pode querer usar um auxiliar de exibição personalizado para renderizar a linha de assunto de um email e o HTML. No caso em que o assistente de exibição está em app / helpers / application_helper.rb , da seguinte maneira:

module ApplicationHelper

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

end

Posso criar uma linha de assunto e modelo de email dinâmicos que usam o auxiliar, mas preciso informar ao Rails para usar o ApplicationHelper explicitamente em apps / mailer / user_mailer.rb de duas maneiras diferentes, como você pode ver na segunda e terceira linhas aqui :

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

Devo mencionar que essas duas linhas funcionam tão bem quanto escolher uma ou outra:

helper :application

add_template_helper(ApplicationHelper)

FWIW, o modelo de email em app / views / user_mailer / party_thanks.html.erb se parece com o seguinte:

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

E o controlador app / controller / party_controller.rb se parece com isso

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

Eu tenho que concordar com a OP (@Tom Lehman) e @gabeodess que tudo isso parece bastante complicado, dado https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers, então talvez eu esteja perdendo alguma coisa .. .

MSC
fonte
5

no meu caso para o Rails4, eu faço assim:

# 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

para que você não precise especificar em add_template_helpertodos os lugares.

Yoshi
fonte