¿Cómo usar mis ayudantes de vista en mis vistas de ActionMailer?


227

Quiero usar los métodos que app/helpers/annotations_helper.rbdefiní en mis vistas de ReportMailer ( app/views/report_mailer/usage_report.text.html.erb). ¿Cómo hago esto?

Según esta guía , parece que el add_template_helper(helper_module)método podría hacer lo que quiero, pero no puedo entender cómo usarlo.

(Por cierto, ¿hay alguna razón por la que tienes acceso a un conjunto diferente de ayudantes en las vistas de correo? Esto es bastante molesto).


Respuestas:


324

En la clase de correo que está utilizando para administrar sus correos electrónicos:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

44
No funciona para mí en este caso (Rails 3.2.8): tengo un método definido en ApplicationController y lo hago un helper por helper_method: my_helper_wannabe, pero el método "my_helper_wannabe" no está disponible en el correo.
Giang Nguyen

Vea la respuesta de Duke a continuación para saber cómo manejar en Rails 3.
Chris Peters

Funciona en Rails 3.2.11
Jan

1
¿Pensé que se suponía que se incluirían automáticamente en Rails 4? guides.rubyonrails.org/…
gabeodess

66
Esta es una respuesta antigua, pero solo replicó para decir que esto funcionó en Rails 5.2
Archonic

158

En Rails 3, solo use el método auxiliar en la parte superior de su clase ActionMailer:

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

Acabo de pasar en un bloque, ya que solo lo necesito en el único Mailer:

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

(asegúrese de configurar config.action_mailer.default_url_options).

(y si usa url_for, asegúrese de pasar: only_path => false)


3
Esto funciona, pero se siente incómodo para volver a especificar los ayudantes ya definidos en ApplicationController a clases individuales de ActionMailer también. ActionMailer extiende ActionController para que provengan de una jerarquía común. Más comentarios sobre Rails que su solución ...
robbie613

3
Y si el ayudante está en un espacio de nombres, puede hacerlohelper :'namespace/mail'
Jonathon Batson

si el asistente está en un espacio de nombres, también acepta solo una cadena (en lugar de un símbolo)helper 'namespace/mail'
Pwnrar

2
¡Funciona en Rails 5.2!
RousseauAlexandre

28

Para todos los anuncios publicitarios en Rails 3 (configuración del asistente de "aplicación"):

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

La mejor respuesta para parciales de correo electrónico compartidos. ¡Gracias!
Alexey Shein

2
NO es cierto: helper :applicationfunciona bien en Rails 4.2.1.
steakchaser

Funciona bien incluso para plantillas de correo electrónico propias devise. helper :applicationNo funciona en este caso.
Sven R.

1
no funciona para 4.2.5.1 - include ApplicationHelperfuncionó
daslicious

23

Para Ruby on Rails 4, tuve que hacer 2 cosas:

(1) Como ya dijo Duke , si el ayudante que desea agregar esUsersHelper por ejemplo, agregar

helper :users

a lo derivado ActionMailer clase (por ejemplo app/mailers/user_mailer.rb)

(2) Después de eso, recibí un nuevo error:

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 solucionar esto, agregue la línea

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

a cada uno de los config/environments/*.rbarchivos. Para config/environments/production.rb, reemplace localhostcon un host más apropiado para las URL generadas por el asistente de producción.


P: Para el n. ° 2, ¿por qué la vista de correo necesita esta información y las vistas normales no?

R: Debido a que las vistas regulares no necesitan saberlo host, ya que todos los enlaces generados se sirven desde el host al que se vinculan. Los enlaces que aparecen en los correos electrónicos no se sirven desde el mismo host (a menos que esté enlazando hotmail.como gmail.com, etc.)


¿Qué pasa con los nombres compuestos? User::ComposedHelper
Cyril Duchon-Doris


17

(Esta es una vieja pregunta, pero Rails ha evolucionado, así que comparto lo que funciona para mí en Rails 5.2).

Por lo general, es posible que desee utilizar un asistente de vista personalizado para representar la línea de asunto de un correo electrónico, así como el HTML. En el caso en que el ayudante de vista esté en app / helpers / application_helper.rb de la siguiente manera:

module ApplicationHelper

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

end

Puedo crear una línea y una plantilla de asunto de correo electrónico dinámico que usan el ayudante, pero necesito decirle a Rails que use el ApplicationHelper explícitamente en apps / mailer / user_mailer.rb de dos maneras diferentes, como puede ver en la segunda y tercera líneas aquí :

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

Debo mencionar que estas dos líneas funcionan igual de bien, así que elija una u otra:

helper :application

add_template_helper(ApplicationHelper)

FWIW, la plantilla de correo electrónico en app / views / user_mailer / party_thanks.html.erb se ve así:

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

Y el controlador app / controller / party_controller.rb se ve así

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

Tengo que estar de acuerdo con OP (@Tom Lehman) y @gabeodess en que todo esto se siente bastante complicado dado https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers, así que quizás me estoy perdiendo algo ... .


5

en mi caso para Rails4, me gusta esto:

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

y

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

para que no tenga que especificar en add_template_helpertodas partes.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.