класс ActionMailer::Base
Action Mailer позволяет отправлять электронные письма из вашего приложения, используя модель и представления почтовых сообщений.
Модели почтовых сообщений
Для использования Action Mailer необходимо создать модель почтового сообщения.
$ bin/rails generate mailer Notifier
Сгенерированная модель наследуется от ApplicationMailer, которая, в свою очередь, наследуется от ActionMailer::Base. Модель почтового сообщения определяет методы, используемые для создания сообщения электронной почты. В этих методах вы можете задавать переменные, которые будут использоваться в представлениях почтовых сообщений, параметры самого письма, такие как адрес :from , и вложения.
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
class NotifierMailer < ApplicationMailer
default from: 'no-reply@example.com',
return_path: 'system@example.com'
def welcome(recipient)
@account = recipient
mail(to: recipient.email_address_with_name,
bcc: ["bcc@example.com", "Order Watcher <watcher@example.com>"])
end
end
Внутри метода почтового сообщения у вас есть доступ к следующим методам:
-
attachments[]=— позволяет добавлять вложения в ваше электронное письмо интуитивно;attachments['filename.png'] = File.read('path/to/filename.png') -
attachments.inline[]=— позволяет добавить встроенное вложение в ваше электронное письмо таким же образом, как иattachments[]= -
headers[]=— позволяет указать любой заголовок поля в вашем электронном письме, напримерheaders['X-No-Spam'] = 'True'. Обратите внимание, что объявление заголовка несколько раз добавит несколько полей с одинаковым именем. Прочитайтеheadersдля получения дополнительной информации. -
headers(hash)— позволяет указать несколько заголовков в вашем электронном письме, таких какheaders({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'}) -
mail— позволяет указать электронное письмо, которое должно быть отправлено.
Хэш, переданный методу mail, позволяет указать любой заголовок, который примет Mail::Message (любой допустимый заголовок электронной почты, включая необязательные поля).
Метод mail, если ему не передан блок, проверит ваши представления и отправит все представления с тем же именем, что и метод, поэтому вышеуказанное действие также отправит файл представления welcome.text.erb, а также файл представления welcome.html.erb в электронном письме multipart/alternative.
Если вы хотите явно отобразить только определенные шаблоны, передайте блок:
mail(to: user.email) do |format| format.text format.html end
Синтаксис блоков также полезен для предоставления информации, специфичной для определённой части:
mail(to: user.email) do |format| format.text(content_transfer_encoding: "base64") format.html end
Или даже для рендеринга специального представления:
mail(to: user.email) do |format|
format.text
format.html { render "some_other_template" }
end
Представления почтовых сообщений
Как и Action Controller, каждый класс почтового сообщения имеет соответствующий каталог представлений, в котором каждый метод класса ищет шаблон с его именем.
Для определения шаблона, используемого с почтовым сообщением, создайте файл .erb с тем же именем, что и метод в вашей модели почтового сообщения. Например, в определенной выше модели почтового сообщения, шаблон в app/views/notifier_mailer/welcome.text.erb будет использоваться для создания электронного письма.
Переменные, определенные в методах вашей модели почтового сообщения, доступны как переменные экземпляра в соответствующем представлении.
По умолчанию электронные письма отправляются в формате простого текста, поэтому пример представления для нашей модели может выглядеть так:
Hi <%= @account.name %>, Thanks for joining our service! Please check back often.
Вы даже можете использовать вспомогательные методы Action View в этих представлениях. Например:
You got a new note! <%= truncate(@note.body, length: 25) %>
Если вам нужно получить доступ к теме, отправителю или получателям в представлении, вы можете сделать это через объект сообщения:
You got a new note from <%= message.from %>! <%= truncate(@note.body, length: 25) %>
Генерация URL-адресов
URL-адреса можно генерировать в представлениях почтовых сообщений с помощью url_for или именованных маршрутов. В отличие от контроллеров из Action Pack, экземпляр почтового сообщения не имеет никакого контекста о входящем запросе, поэтому вам нужно предоставить все необходимые детали для генерации URL-адреса.
При использовании url_for вам нужно предоставить :host, :controller, и :action.
<%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>
При использовании именованных маршрутов вам нужно указать только :host:
<%= users_url(host: "example.com") %>
Вы должны использовать стиль named_route_url (который генерирует абсолютные URL-адреса) и избегать использования стиля named_route_path (который генерирует относительные URL-адреса), так как клиенты, читающие электронное письмо, не будут знать текущего URL-адреса, чтобы определить относительный путь.
Также можно установить хост по умолчанию, который будет использоваться во всех почтовых сообщениях, установив параметр :host в качестве конфигурационного параметра в config/application.rb:
config.action_mailer.default_url_options = { host: "example.com" }
Вы также можете определить метод default_url_options в отдельных почтовых сообщениях, чтобы переопределить эти параметры по умолчанию для каждого почтового сообщения.
По умолчанию, когда config.force_ssl равен true, URL-адреса, сгенерированные для хостов, будут использовать протокол HTTPS.
Отправка почты
После определения действия почтового сообщения и шаблона вы можете доставить ваше сообщение или отложить его создание и доставку на более позднее время:
NotifierMailer.welcome(User.first).deliver_now # sends the email mail = NotifierMailer.welcome(User.first) # => an ActionMailer::MessageDelivery object mail.deliver_now # generates and sends the email now
Класс ActionMailer::MessageDelivery — это обёртка вокруг делегата, который вызовет ваш метод для создания почты. Если вам нужен прямой доступ к делегату или Mail::Message, вы можете вызвать метод message на объекте ActionMailer::MessageDelivery.
NotifierMailer.welcome(User.first).message # => a Mail::Message object
Action Mailer отлично интегрирован с Active Job, поэтому вы можете создавать и отправлять электронные письма в фоновом режиме (например, вне цикла запроса-ответа, чтобы пользователь не должен был ждать):
NotifierMailer.welcome(User.first).deliver_later # enqueue the email sending to Active Job
Обратите внимание, что deliver_later выполнит ваш метод из фоновой задачи.
Вы никогда не создаёте экземпляр вашего класса почтового сообщения. Вместо этого вы просто вызываете метод, который вы определили в самом классе. Ожидается, что все методы экземпляра вернут объект сообщения, который необходимо отправить.
Электронные письма с несколькими частями
Сообщения с несколькими частями также могут использоваться неявно, потому что Action Mailer автоматически обнаруживает и использует шаблоны с несколькими частями, где каждый шаблон называется по имени действия, за которым следует тип содержимого. Каждый такой обнаруженный шаблон будет добавлен к сообщению как отдельная часть.
Например, если существуют следующие шаблоны:
-
signup_notification.text.erb
-
signup_notification.html.erb
-
signup_notification.xml.builder
-
signup_notification.yml.erb
Каждый из них будет рендериться и добавляться как отдельная часть к сообщению с соответствующим типом содержимого. Тип содержимого для всего сообщения автоматически устанавливается в multipart/alternative, что указывает на то, что электронное письмо содержит несколько различных представлений одного и того же тела электронного письма. Те же переменные экземпляра, определённые в действии, передаются во все шаблоны электронных писем.
Неявный рендеринг шаблонов не выполняется, если в электронное письмо были добавлены какие-либо вложения или части. Это означает, что вам нужно вручную добавить каждую часть в электронное письмо и установить тип содержимого электронного письма в multipart/alternative.
Вложения
Отправка вложений в электронные письма проста:
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments['free_book.pdf'] = File.read('path/to/file.pdf')
mail(to: recipient, subject: "New account information")
end
end
Что будет (если в каталоге представлений будут и welcome.text.erb, и welcome.html.erb шаблон), отправлять полное multipart/mixed электронное письмо с двумя частями: первая часть — multipart/alternative с текстовой и HTML-частями электронного письма внутри, а вторая — application/pdf с закодированной в Base64 копией файла book.pdf с именем файла free_book.pdf.
Если вам нужно отправить вложения без содержимого, необходимо создать для них пустое представление или добавить пустой параметр body, как в этом примере:
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments['free_book.pdf'] = File.read('path/to/file.pdf')
mail(to: recipient, subject: "New account information", body: "")
end
end
Вы также можете отправлять вложения с шаблоном html, в этом случае вам нужно добавить body, attachments и пользовательский тип содержимого, как в этом примере:
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments["free_book.pdf"] = File.read("path/to/file.pdf")
mail(to: recipient,
subject: "New account information",
content_type: "text/html",
body: "<html><body>Hello there</body></html>")
end
end
Встроенные вложения
Вы также можете указать, что файл должен отображаться встроенным образом вместе с другим HTML. Это полезно, если вы хотите отобразить логотип компании или фотографию.
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments.inline['photo.png'] = File.read('path/to/photo.png')
mail(to: recipient, subject: "Here is what we look like")
end
end
Затем, чтобы сослаться на изображение в представлении, вы создаёте файл welcome.html.erb и вызываете image_tag, передавая в него вложение, которое вы хотите отобразить, а затем вызываете url на вложении, чтобы получить относительный путь идентификатора содержимого для источника изображения:
<h1>Please Don't Cringe</h1> <%= image_tag attachments['photo.png'].url -%>
Поскольку мы используем метод image_tag Action View, вы можете передать любые другие параметры, которые вы хотите:
<h1>Please Don't Cringe</h1> <%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>
Наблюдение и перехват почты
Action Mailer предоставляет крючки для наблюдателя и методов перехвата Mail. Они позволяют вам регистрировать классы, которые вызываются в течение жизненного цикла доставки почты.
Класс наблюдателя должен реализовать метод :delivered_email(message), который будет вызываться один раз для каждого отправленного электронного письма после отправки электронного письма.
Класс перехватчика должен реализовать метод :delivering_email(message), который будет вызываться перед отправкой электронного письма, позволяя вносить изменения в электронное письмо перед его доставкой агентами доставки. Ваш класс должен вносить необходимые изменения непосредственно в переданный экземпляр Mail::Message.
Значения по умолчанию Hash
Action Mailer предоставляет некоторые разумные значения по умолчанию для ваших электронных писем, они обычно задаются в методе по умолчанию внутри определения класса:
class NotifierMailer < ApplicationMailer default sender: 'system@example.com' end
Вы можете передать любое значение заголовка, которое принимает Mail::Message. Встроенный ActionMailer::Base устанавливает следующие значения:
-
mime_version: "1.0" -
charset: "UTF-8" -
content_type: "text/plain" -
parts_order: [ "text/plain", "text/enriched", "text/html" ]
parts_order и charset на самом деле не являются допустимыми полями заголовка Mail::Message, но Action Mailer переводит их соответствующим образом и задаёт правильные значения.
Поскольку вы можете передать любое значение заголовка, вам нужно либо привести заголовок к строке, либо передать его как подчеркнутый символ, поэтому следующее будет работать:
class NotifierMailer < ApplicationMailer
default 'Content-Transfer-Encoding' => '7bit',
content_description: 'This is a description'
end
Наконец, Action Mailer также поддерживает передачу объектов Proc и Lambda в хэш по умолчанию, поэтому вы можете определить методы, которые будут вычисляться по мере создания сообщения:
class NotifierMailer < ApplicationMailer
default 'X-Special-Header' => Proc.new { my_method }, to: -> { @inviter.email_address }
private
def my_method
'some complex call'
end
end
Обратите внимание, что процедура/лямбда вычисляется в самом начале генерации сообщения электронной почты, поэтому если вы установите что-либо в хэш по умолчанию с помощью процедуры, а затем установите то же самое в методе вашего почтового сообщения, метод почтового сообщения перезапишет это значение.
Также возможно установить эти параметры по умолчанию, которые будут использоваться во всех почтовых сообщениях, через конфигурацию default_options= в config/application.rb:
config.action_mailer.default_options = { from: "no-reply@example.org" }
Обработчики событий
Вы можете указать обработчики событий, используя before_action и after_action для настройки ваших сообщений. Это может быть полезно, например, когда вы хотите добавить встроенные вложения по умолчанию для всех сообщений, отправляемых определённым классом почтового сообщения:
class NotifierMailer < ApplicationMailer
before_action :add_inline_attachment!
def welcome
mail
end
private
def add_inline_attachment!
attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
end
end
Обработчики событий в Action Mailer реализуются с помощью AbstractController::Callbacks, поэтому вы можете определить и настроить обработчики событий так же, как и в классах, наследуемых от ActionController::Base.
Обратите внимание, что если у вас нет особой причины, вы должны предпочесть использовать before_action вместо after_action в ваших классах Action Mailer, чтобы заголовки обрабатывались должным образом.
Предварительный просмотр писем
Вы можете визуально просмотреть шаблоны своих писем, добавив файл предварительного просмотра почтового клиента в ActionMailer::Base.preview_path. Поскольку большинство писем используют данные из базы данных, вам необходимо написать сценарии для загрузки сообщений с фиктивными данными:
class NotifierMailerPreview < ActionMailer::Preview
def welcome
NotifierMailer.welcome(User.first)
end
end
Методы должны возвращать объект Mail::Message, который можно сгенерировать, вызвав метод почтового клиента без дополнительных deliver_now / deliver_later. Путь к каталогу предварительного просмотра почтовых клиентов можно настроить с помощью параметра preview_path, который имеет значение по умолчанию test/mailers/previews:
config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
Обзор всех предварительных просмотров доступен по адресу http://localhost:3000/rails/mailers на экземпляре работающего сервера разработки.
Previews также можно перехватить аналогичным образом, как и доставки, зарегистрировав перехватчик предварительного просмотра, у которого есть метод previewing_email:
class CssInlineStyler
def self.previewing_email(message)
# inline CSS styles
end
end
config.action_mailer.preview_interceptors :css_inline_styler
Обратите внимание, что перехватчики необходимо регистрировать как в register_interceptor, так и в register_preview_interceptor, если они должны работать как с отправкой, так и с предварительным просмотром писем.
Параметры настройки
Эти параметры задаются на уровне класса, как ActionMailer::Base.raise_delivery_errors = true
-
default_options- Вы можете передать его как на уровне класса, так и внутри самого класса, как указано в разделе выше. -
logger- Логгер используется для создания информации о выполнении рассылки, если доступен. Может быть установлен наnilдля отключения ведения журнала. Совместим с собственными логгерами RubyLoggerи логгерами Log4r. -
smtp_settings- Позволяет детальную настройку метода доставки:smtp:-
:address- Позволяет использовать удаленный SMTP-сервер. Просто измените его со значения по умолчанию "localhost". -
:port- В случае, если ваш SMTP-сервер не работает на порту 25, вы можете изменить его. -
:domain- Если необходимо указать домен HELO, вы можете сделать это здесь. -
:user_name- Если ваш SMTP-сервер требует аутентификации, укажите имя пользователя в этом параметре. -
:password- Если ваш SMTP-сервер требует аутентификации, укажите пароль в этом параметре. -
:authentication- Если ваш SMTP-сервер требует аутентификации, укажите здесь тип аутентификации. Это символ, и один из:plain(будет отправлять пароль в кодировке Base64),:login(будет отправлять пароль в кодировке Base64) или:cram_md5(комбинирует механизм Challenge/Response для обмена информацией и криптографический алгоритм MessageDigest5 для хеширования важной информации) -
:enable_starttls_auto- Обнаруживает, включен ли STARTTLS на вашем SMTP-сервере, и начинает его использовать. По умолчаниюtrue. -
:openssl_verify_mode- При использовании TLS вы можете настроить, как OpenSSL проверяет сертификат. Это очень полезно, если вам нужно проверить самозаверяющий и/или сертификат с подстановочными знаками. Вы можете использовать имя константы OpenSSL для проверки ('none'или'peer') или непосредственно константу (OpenSSL::SSL::VERIFY_NONEилиOpenSSL::SSL::VERIFY_PEER). -
:ssl/:tlsВключает использование SMTP/TLS (SMTPS: SMTP по прямому TLS-соединению) для подключения SMTP.
-
-
sendmail_settings- Позволяет переопределить параметры для метода доставки:sendmail.-
:location- Путь к исполняемому файлу sendmail. По умолчанию/usr/sbin/sendmail. -
:arguments- Аргументы командной строки. По умолчанию-iс-f sender@addressавтоматически добавленными перед отправкой сообщения.
-
-
file_settings- Позволяет переопределить параметры для метода доставки:file.-
:location- Каталог, в который будут записаны письма. По умолчаниюtmp/mails.
-
-
raise_delivery_errors- Флаг, определяющий, следует ли генерировать ошибки, если письмо не было доставлено. -
delivery_method- Определяет метод доставки. Возможные значения:smtp(по умолчанию),:sendmail,:test, и:file. Или вы можете предоставить объект пользовательского метода доставки, например,MyOwnDeliveryMethodClass. Обратитесь к документации поMailgem для получения информации о требуемом интерфейсе для пользовательского агента доставки. -
perform_deliveries- Определяет, отправляются ли письма из Action Mailer при вызове.deliverна сообщение электронной почты или на метод Action Mailer. Это включено по умолчанию, но может быть выключено для облегчения функционального тестирования. -
deliveries- Сохраняет массив всех отправленных писем через Action Mailer сdelivery_method :test. Очень полезно для модульного и функционального тестирования. -
deliver_later_queue_name- Имя очереди, используемой сdeliver_later. По умолчаниюmailers.
Константы
- PROTECTED_IVARS
Атрибуты
Позволяет установить имя текущего почтового отправителя.
Публичные методы класса
# File actionmailer/lib/action_mailer/base.rb, line 541 def default(value = nil) self.default_params = default_params.merge(value).freeze if value default_params end
Устанавливает значения по умолчанию через конфигурацию приложения:
config.action_mailer.default(from: "no-reply@example.org")
Псевдоним ::default_options=
Позволяет установить значения по умолчанию через конфигурацию приложения:
config.action_mailer.default_options = { from: "no-reply@example.org" }
# File actionmailer/lib/action_mailer/base.rb, line 564
def email_address_with_name(address, name)
Mail::Address.new.tap do |builder|
builder.address = address
builder.display_name = name
end.to_s
end Возвращает электронный адрес в формате “Имя <email@example.com>”.
# File actionmailer/lib/action_mailer/base.rb, line 529 def mailer_name @mailer_name ||= anonymous? ? "anonymous" : name.underscore end
Возвращает имя текущего почтового отправителя. Этот метод также используется в качестве пути для поиска представления. Если это анонимный почтовый отправитель, этот метод вернет anonymous вместо этого.
# File actionmailer/lib/action_mailer/base.rb, line 601 def initialize super() @_mail_was_called = false @_message = Mail.new end
# File actionmailer/lib/action_mailer/base.rb, line 506 def register_interceptor(interceptor) Mail.register_interceptor(observer_class_for(interceptor)) end
Регистрирует перехватчик, который будет вызываться перед отправкой письма. В качестве перехватчика может быть передан класс, строка или символ. Если передается строка или символ, он будет приведен к верблюжьему регистру и константизирован.
# File actionmailer/lib/action_mailer/base.rb, line 480
def register_interceptors(*interceptors)
interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
end Регистрирует один или несколько перехватчиков, которые будут вызываться перед отправкой письма.
# File actionmailer/lib/action_mailer/base.rb, line 492 def register_observer(observer) Mail.register_observer(observer_class_for(observer)) end
Регистрирует наблюдателя, который будет уведомлен при доставке письма. В качестве наблюдателя может быть передан класс, строка или символ. Если передается строка или символ, он будет приведен к верблюжьему регистру и константизирован.
# File actionmailer/lib/action_mailer/base.rb, line 470
def register_observers(*observers)
observers.flatten.compact.each { |observer| register_observer(observer) }
end Регистрирует одного или нескольких наблюдателей, которые будут уведомлены при доставке письма.
# File actionmailer/lib/action_mailer/base.rb, line 513 def unregister_interceptor(interceptor) Mail.unregister_interceptor(observer_class_for(interceptor)) end
Отменяет регистрацию ранее зарегистрированного перехватчика. В качестве перехватчика может быть передан класс, строка или символ. Если передается строка или символ, он будет приведен к верблюжьему регистру и константизирован.
# File actionmailer/lib/action_mailer/base.rb, line 485
def unregister_interceptors(*interceptors)
interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
end Отменяет регистрацию одного или нескольких ранее зарегистрированных перехватчиков.
# File actionmailer/lib/action_mailer/base.rb, line 499 def unregister_observer(observer) Mail.unregister_observer(observer_class_for(observer)) end
Отменяет регистрацию ранее зарегистрированного наблюдателя. В качестве наблюдателя может быть передан класс, строка или символ. Если передается строка или символ, он будет приведен к верблюжьему регистру и константизирован.
# File actionmailer/lib/action_mailer/base.rb, line 475
def unregister_observers(*observers)
observers.flatten.compact.each { |observer| unregister_observer(observer) }
end Отменяет регистрацию одного или нескольких ранее зарегистрированных наблюдателей.
Приватные методы класса
# File actionmailer/lib/action_mailer/base.rb, line 897 def self.supports_path? # :doc: false end
Электронные письма не поддерживают ссылки с относительными путями.
Публичные методы экземпляра
# File actionmailer/lib/action_mailer/base.rb, line 715
def attachments
if @_mail_was_called
LateAttachmentsProxy.new(@_message.attachments)
else
@_message.attachments
end
end Позволяет добавить вложения в электронное письмо, например так:
mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
Если вы это сделаете, то Mail получит имя файла и определит тип MIME. Также будет установлено Content-Type, Content-Disposition, Content-Transfer-Encoding, и содержимое вложения будет закодировано в Base64.
Вы также можете указать переопределения, передав хеш вместо строки:
mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
content: File.read('/path/to/filename.jpg')}
Если вы хотите использовать кодировку, отличную от Base64, то вам необходимо передать тип кодировки вместе с предварительно закодированным содержимым, так как Mail не знает, как декодировать данные:
file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
encoding: 'SpecialEncoding',
content: file_content }
Вы также можете искать определённые вложения:
# By Filename mail.attachments['filename.jpg'] # => Mail::Part object or nil # or by index mail.attachments[0] # => Mail::Part (first attachment)
# File actionmailer/lib/action_mailer/base.rb, line 639 def email_address_with_name(address, name) self.class.email_address_with_name(address, name) end
Возвращает адрес электронной почты в формате «Имя <email@example.com>».
# File actionmailer/lib/action_mailer/base.rb, line 677
def headers(args = nil)
if args
@_message.headers(args)
else
@_message
end
end Позволяет передавать произвольные и необычные заголовки новому Mail::Message объекту, который добавит их к себе.
headers['X-Special-Domain-Specific-Header'] = "SecretValue"
Вы также можете передать хеш с именами и значениями заголовков, которые затем будут установлены на Mail::Message объекте:
headers 'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => incoming.message_id
Получившийся Mail::Message объект будет содержать следующие заголовки:
X-Special-Domain-Specific-Header: SecretValue
Примечание о замене уже определённых заголовков:
-
subject -
sender -
from -
to -
cc -
bcc -
reply-to -
orig-date -
message-id -
references
Поля могут появляться только один раз в заголовках электронного письма, в то время как другие поля, такие как X-Anything, могут появляться многократно.
Если вы хотите заменить существующий заголовок, сначала установите его в nil для сброса значения, иначе для этого заголовка будет добавлено другое поле.
# File actionmailer/lib/action_mailer/base.rb, line 824
def mail(headers = {}, &block)
return message if @_mail_was_called && headers.blank? && !block
# At the beginning, do not consider class default for content_type
content_type = headers[:content_type]
headers = apply_defaults(headers)
# Apply charset at the beginning so all fields are properly quoted
message.charset = charset = headers[:charset]
# Set configure delivery behavior
wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options])
assign_headers_to_message(message, headers)
# Render the templates and blocks
responses = collect_responses(headers, &block)
@_mail_was_called = true
create_parts_from_responses(message, responses)
wrap_inline_attachments(message)
# Set up content type, reapply charset and handle parts order
message.content_type = set_content_type(message, content_type, headers[:content_type])
message.charset = charset
if message.multipart?
message.body.set_sort_order(headers[:parts_order])
message.body.sort_parts!
end
message
end Основной метод, создающий сообщение и отображающий шаблоны электронных писем. Этот метод можно вызвать двумя способами: с блоком или без него.
Он принимает хеш заголовков. Этот хеш позволяет указать наиболее часто используемые заголовки в сообщении электронной почты, это:
-
:subject- Тема сообщения. Если она отсутствует, Action Mailer обратится к классу Rails I18n за переведённой:subject, в контексте[mailer_scope, action_name], или, если это также отсутствует, переведёт гуманизированную версиюaction_name. -
:to- Получатели сообщения. Может быть строкой адресов или массивом адресов. -
:from- Отправитель сообщения. -
:cc- Копия сообщения. Может быть строкой адресов или массивом адресов. -
:bcc- Скрытая копия сообщения. Может быть строкой адресов или массивом адресов. -
:reply_to- Адрес для ответа. -
:date- Дата отправки письма.
Вы можете установить значения по умолчанию для любых из вышеперечисленных заголовков (кроме :date) с помощью метода класса ::default:
class Notifier < ActionMailer::Base
default from: 'no-reply@test.lindsaar.net',
bcc: 'email_logger@test.lindsaar.net',
reply_to: 'bounces@test.lindsaar.net'
end
Если вам нужны другие заголовки, не указанные выше, вы можете либо передать их в качестве части хеша заголовков, либо использовать метод headers['name'] = value.
Когда :return_path задан как заголовок, это значение будет использоваться в качестве адреса «отправителя» для сообщения Mail. Это полезно, когда вы хотите получать уведомления о доставке по другому адресу, чем указанный в :from. Mail фактически будет использовать :return_path в приоритете над :sender в приоритете над :from полем для значения «отправителя».
Если вы не передаете блок методу mail, он найдет все шаблоны в путях представления, используя по умолчанию имя маиллера и имя метода, из которого он вызывается. Он затем создаст части для каждого из этих шаблонов интеллектуально, делая обоснованные предположения о правильном типе содержимого и последовательности, и вернет полностью подготовленное Mail::Message для вызова :deliver для отправки.
Например:
class Notifier < ActionMailer::Base
default from: 'no-reply@test.lindsaar.net'
def welcome
mail(to: 'mikel@test.lindsaar.net')
end
end
Будет искать все шаблоны в “app/views/notifier” с именем “welcome”. Если шаблон welcome не существует, будет выброшено исключение ActionView::MissingTemplate.
Однако это можно настроить:
mail(template_path: 'notifications', template_name: 'another')
Теперь будет искаться все шаблоны в “app/views/notifications” с именем “another”.
Если вы передаете блок, вы можете отображать конкретные шаблоны по вашему выбору:
mail(to: 'mikel@test.lindsaar.net') do |format| format.text format.html end
Вы даже можете отобразить простой текст напрямую, не используя шаблон:
mail(to: 'mikel@test.lindsaar.net') do |format|
format.text { render plain: "Hello Mikel!" }
format.html { render html: "<h1>Hello Mikel!</h1>".html_safe }
end
Что отобразит multipart/alternative электронное письмо с text/plain и text/html частями.
Синтаксис блока также позволяет настроить заголовки частей, если необходимо:
mail(to: 'mikel@test.lindsaar.net') do |format| format.text(content_transfer_encoding: "base64") format.html end
# File actionmailer/lib/action_mailer/base.rb, line 634 def mailer_name self.class.mailer_name end
Возвращает имя объекта маиллера.
Приватные методы экземпляра
# File actionmailer/lib/action_mailer/base.rb, line 891
def default_i18n_subject(interpolations = {}) # :doc:
mailer_scope = self.class.mailer_name.tr("/", ".")
I18n.t(:subject, **interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
end Переводит subject с помощью класса Rails I18n в контексте [mailer_scope, action_name]. Если перевод для subject в указанном контексте не найден, используется гуманизированная версия action_name. Если тема содержит интерполяции, вы можете передать их через параметр interpolations.
# File actionmailer/lib/action_mailer/base.rb, line 869
def set_content_type(m, user_content_type, class_default) # :doc:
params = m.content_type_parameters || {}
case
when user_content_type.present?
user_content_type
when m.has_attachments?
if m.attachments.all?(&:inline?)
["multipart", "related", params]
else
["multipart", "mixed", params]
end
when m.multipart?
["multipart", "alternative", params]
else
m.content_type || class_default
end
end Используется методом mail для установки типа содержимого сообщения.
Используется переданный user_content_type, или multipart, если сообщение содержит вложения. Если вложения находятся встроены, тип содержимого будет «multipart/related», иначе «multipart/mixed».
Если тип содержимого не передан через заголовки, и нет вложений, или сообщение является multipart, используется тип содержимого по умолчанию.
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.