243 votes

Comment utiliser mes aides de vue dans mes vues ActionMailer ?

Je veux utiliser les méthodes que j'ai définies dans app/helpers/annotations_helper.rb dans mes vues ReportMailer ( app/views/report_mailer/usage_report.text.html.erb ). Comment dois-je m'y prendre ?

Sur la base de ce guide il semble que le add_template_helper(helper_module) La méthode pourrait faire ce que je veux, mais je n'arrive pas à savoir comment l'utiliser.

(BTW, y a-t-il une raison pour laquelle vous avez accès à un ensemble différent d'aides dans les vues de mailer ? C'est assez ennuyeux).

0 votes

342voto

Mark Connell Points 1676

Dans la classe mailer que vous utilisez pour gérer vos emails :

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

4 votes

Cela ne fonctionne pas pour moi dans ce cas (Rails 3.2.8) : J'ai une méthode définie dans ApplicationController et j'en fais un helper par helper_method :my_helper_wannabe, mais la méthode "my_helper_wannabe" ne devient pas disponible dans mailer.

0 votes

Voir la réponse de Duke ci-dessous pour savoir comment gérer cette situation dans Rails 3.

0 votes

Cela a fonctionné pour moi dans Rails 3.2.13. Une chose à noter : j'ai dû redémarrer mon serveur avant que la modification ne soit prise en compte.

167voto

Duke Points 2752

Dans Rails 3, il suffit d'utiliser la méthode d'aide au sommet de votre classe ActionMailer :

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

J'ai juste passé dans un bloc, puisque je n'en ai besoin que dans un seul Mailer :

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

(assurez-vous de définir config.action_mailer.default_url_options.)

(et si vous utilisez url_for, assurez-vous de passer dans :only_path => false)

3 votes

Cela fonctionne, mais il est difficile de spécifier à nouveau les aides déjà définies dans ApplicationController pour les classes ActionMailer individuelles également. ActionMailer étend ActionController de sorte qu'ils proviennent d'une hiérarchie commune. C'est plus un commentaire sur Rails que votre solution...

3 votes

Et si l'aide est dans un espace de nom, vous pouvez faire helper :'namespace/mail'

0 votes

Si l'aide est dans un espace de nom, elle accepte également une chaîne de caractères (au lieu d'un symbole). helper 'namespace/mail'

29voto

Edison Machado Points 747

Pour tous les mailers dans Rails 3 (réglage de l'aide "application") :

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

0 votes

La meilleure réponse pour les partiels d'emails partagés. Merci !

2 votes

PAS VRAI - helper :application fonctionne bien dans Rails 4.2.1.

0 votes

Cela fonctionne bien, même pour les modèles d'e-mails personnels pour devise . helper :application ne fonctionne pas dans ce cas.

27voto

MSC Points 62

(Il s'agit d'une vieille question mais Rails a évolué et je partage donc ce qui fonctionne pour moi dans Rails 5.2).

En général, vous pouvez utiliser une aide de vue personnalisée pour rendre la ligne d'objet d'un courriel ainsi que le HTML. Dans le cas où l'aide d'affichage se trouve dans le fichier app/helpers/application_helper.rb comme suit :

module ApplicationHelper

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

end

Je peux créer une ligne d'objet et un modèle d'e-mail dynamiques qui utilisent tous deux l'aide, mais je dois indiquer à Rails d'utiliser l'ApplicationHelper de manière explicite dans le champ apps/mailer/user_mailer.rb de deux manières différentes, comme vous pouvez le voir dans les deuxième et troisième lignes ici :

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

Je dois préciser que ces deux lignes fonctionnent tout aussi bien, alors choisissez l'une ou l'autre :

helper :application

add_template_helper(ApplicationHelper)

Pour info, le modèle d'email à app/views/user_mailer/party_thanks.html.erb ressemble à ça :

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

Et le app/controller/party_controller.rb Le contrôleur ressemble à ceci

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

Je dois être d'accord avec l'OP (@Tom Lehman) et @gabeodess pour dire que tout ceci semble assez alambiqué étant donné https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers alors peut-être que je manque quelque chose...

26voto

Matt Points 9560

Pour Ruby on Rails 4, j'ai dû faire 2 choses :

(1) Comme Duke déjà dit, si l'aide que vous voulez ajouter est UsersHelper par exemple, puis ajoutez

helper :users

au dérivé ActionMailer (par exemple app/mailers/user_mailer.rb )

(2) Après cela, j'ai eu une nouvelle erreur :

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

Pour corriger cela, ajoutez la ligne

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

à chacun des config/environments/*.rb les dossiers. Pour config/environments/production.rb , remplacer localhost avec un hôte plus approprié pour les urls générées par l'aide à la production.


Q : Pour le point 2, pourquoi la vue du courrier a-t-elle besoin de cette information, alors que les vues ordinaires n'en ont pas besoin ?

R : Parce que les vues régulières n'ont pas besoin de connaître la host Les liens qui apparaissent dans les courriels ne sont pas servis par le même hôte. Les liens qui apparaissent dans les courriels ne sont pas servis par le même hôte (à moins que vous ne fassiez un lien vers le site de hotmail.com ou gmail.com etc.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X