web-dev-qa-db-fra.com

Rails ActionMailer - format de l'expéditeur et du destinataire nom / adresse e-mail

Existe-t-il un moyen de spécifier l'adresse e-mail ET le nom de l'expéditeur et du destinataire lors de l'utilisation d'ActionMailer?

En règle générale, vous feriez:

@recipients   = "#{user.email}"
@from         = "[email protected]"
@subject      = "Hi"
@content_type = "text/html"

Mais, je veux également spécifier le nom-- MyCompany <[email protected]>, John Doe <john.doe@mycompany>.

Y-a-t-il un moyen de faire ça?

108
Grnbeagle

Si vous acceptez l'entrée d'utilisateur pour le nom et l'e-mail, à moins que vous ne validiez ou n'échappiez très soigneusement au nom et à l'e-mail, vous pouvez vous retrouver avec un en-tête From non valide en concaténant simplement des chaînes. Voici un moyen sûr:

require 'mail'
address = Mail::Address.new email # ex: "[email protected]"
address.display_name = name.dup   # ex: "John Doe"
# Set the From or Reply-To header to the following:
address.format # returns "John Doe <[email protected]>"
231
James McKinney
@recipients   = "\"#{user.name}\" <#{user.email}>"
@from         = "\"MyCompany\" <[email protected]>"
97
Eduardo Scoz

Dans Rails3, je place les éléments suivants dans chaque environnement. c'est-à-dire production.rb

ActionMailer::Base.default :from => "Company Name <[email protected]>"

Placer des devis autour du nom de l'entreprise n'a pas fonctionné pour moi dans Rails3.

42
astjohn

dans Rails 2.3.3 un bug dans ActionMailer a été introduit. Vous pouvez voir le ticket ici Ticket # 234 . Il est résolu dans 2-3-stable et master il sera donc corrigé dans 3.x et 2.3.6.

Pour résoudre le problème dans 2.3. *, Vous pouvez utiliser le code fourni dans les commentaires du ticket:

module ActionMailer
  class Base
    def perform_delivery_smtp(mail)
      destinations = mail.destinations
      mail.ready_to_send
      sender = (mail['return-path'] && mail['return-path'].spec) || Array(mail.from).first

      smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
      smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
      smtp.start(smtp_settings[:domain], smtp_settings[:user_name], smtp_settings[:password],
                 smtp_settings[:authentication]) do |smtp|
        smtp.sendmail(mail.encoded, sender, destinations)
      end
    end
  end
end
8
anka

La version que j'aime utiliser est

%`"#{account.full_name}" <#{account.email}>`

`<< sont des astuces.

Mise à jour

Vous pouvez également changer cela en

%|"#{account.full_name}" <#{account.email}>|
%\"#{account.full_name}" <#{account.email}>\
%^"#{account.full_name}" <#{account.email}>^
%["#{account.full_name}" <#{account.email}>]

En savoir plus sur les littéraux de chaîne.

6
Marc

Un autre aspect irritant, au moins avec le nouveau format AR, est de se rappeler que "par défaut" est appelé au niveau de la classe. Le fait de référencer des routines qui ne sont que des instances le fait échouer et donner silencieusement lorsque vous essayez de l'utiliser:

 NoMethodError: undefined method `new_post' for Notifier:Class

Voici ce que j'ai fini par utiliser:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
1
Kevin