Spec-Zone.ru › Ruby on Rails 8.1

class ActionMailer::Base

Родительский класс:
AbstractController::Base
Подключенные модули:
ActionMailer::Callbacks, ActionMailer::DeliveryMethods, ActionMailer::QueuedDelivery, ActionMailer::Rescuable, ActionMailer::Parameterized, ActionMailer::Previews, ActionMailer::FormBuilder, AbstractController::Rendering, AbstractController::Helpers, AbstractController::Translation, AbstractController::Callbacks, AbstractController::Caching, ActionView::Layouts

Базовый класс Action Mailer

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) %>

Если в представлении нужен доступ к теме, отправителю или получателям, это можно сделать через объект message:

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 с файлом file.pdf, закодированным в Base64, и именем файла 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, вложения и пользовательский тип содержимого, например:

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.

Хэш параметров по умолчанию

Action Mailer задаёт для писем ряд разумных значений по умолчанию. Обычно их указывают в методе default внутри определения класса:

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

Обратите внимание: proc/lambda вычисляется сразу в начале создания почтового сообщения. Поэтому если установить значение в хэше параметров по умолчанию с помощью proc, а затем установить то же значение в методе почтовой программы, значение из хэша будет перезаписано методом почтовой программы.

Также можно задать параметры по умолчанию, которые будут использоваться во всех почтовых программах, с помощью конфигурации default_options= в config/application.rb:

config.action_mailer.default_options = { from: "no-reply@example.org" }

Обратные вызовы

Для настройки сообщений можно указать обратные вызовы с помощью before_action и after_action, а для обёртывания процесса доставки — с помощью before_deliver и after_deliver. Например, если нужно добавить стандартные встроенные вложения и вести журнал доставки для всех сообщений, отправляемых определённым классом почтовой программы:

class NotifierMailer < ApplicationMailer
  before_action :add_inline_attachment!
  after_deliver :log_delivery

  def welcome
    mail
  end

  private
    def add_inline_attachment!
      attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
    end

    def log_delivery
      Rails.logger.info "Sent email with message id '#{message.message_id}' at #{Time.current}."
    end
end

Обратные вызовы действий в Action Mailer реализованы с помощью AbstractController::Callbacks, поэтому их можно определять и настраивать так же, как обратные вызовы в классах, наследующихся от ActionController::Base.

Обратите внимание: если у вас нет особой причины поступать иначе, в классах Action Mailer следует использовать before_action вместо after_action, чтобы заголовки разбирались правильно.

Обработка ошибок

Блоки rescue внутри метода почтовой программы не могут перехватывать ошибки, возникающие вне этапа рендеринга, например ошибки десериализации записи в фоновой задаче или ошибки сторонней службы доставки почты.

Чтобы перехватывать ошибки, возникающие на любом этапе отправки письма, используйте rescue_from:

class NotifierMailer < ApplicationMailer
  rescue_from ActiveJob::DeserializationError do
    # ...
  end

  rescue_from "SomeThirdPartyService::ApiError" do
    # ...
  end

  def notify(recipient)
    mail(to: recipient, subject: "Notification")
  end
end

Предварительный просмотр писем

Можно визуально просматривать шаблоны писем, добавив файл предварительного просмотра почтовой программы в ActionMailer::Base.preview_paths. Поскольку большинство писем использует данные из базы данных, для загрузки сообщений с фиктивными данными необходимо написать несколько сценариев:

class NotifierMailerPreview < ActionMailer::Preview
  def welcome
    NotifierMailer.welcome(User.first)
  end
end

Методы должны возвращать объект Mail::Message, который можно получить, вызвав метод почтовой программы без дополнительных deliver_now / deliver_later. Расположение каталогов предварительного просмотра почтовых программ можно настроить с помощью параметра preview_paths, значение которого по умолчанию — test/mailers/previews:

config.action_mailer.preview_paths << "#{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. Совместим как со встроенным в Ruby Logger, так и с журналами Log4r.

  • smtp_settings — позволяет подробно настроить способ доставки :smtp:

    • :address — позволяет использовать удалённый почтовый сервер. Для этого измените значение по умолчанию — «localhost».

    • :port — если почтовый сервер работает не на порту 25, здесь можно указать другой порт.

    • :domain — здесь можно указать домен HELO, если это необходимо.

    • :user_name — если для почтового сервера требуется аутентификация, укажите здесь имя пользователя.

    • :password — если для почтового сервера требуется аутентификация, укажите здесь пароль.

    • :authentication — если для почтового сервера требуется аутентификация, здесь необходимо указать её тип. Это символ, принимающий одно из значений: :plain (пароль будет отправлен в кодировке Base64), :login (пароль будет отправлен в кодировке Base64) или :cram_md5 (объединяет механизм Challenge/Response для обмена данными и криптографический алгоритм Message Digest 5 для хеширования важных данных).

    • :enable_starttls — использовать STARTTLS при подключении к SMTP-серверу и завершать работу с ошибкой, если протокол не поддерживается. По умолчанию задано значение false. Требуется версия 2.7 или выше гем-пакета Mail.

    • :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-подключению использовать SMTP/TLS (SMTPS: SMTP через прямое TLS-подключение).

    • :open_timeout Количество секунд ожидания при попытке установить соединение.

    • :read_timeout Количество секунд ожидания до истечения времени ожидания вызова read(2).

  • sendmail_settings — позволяет переопределить параметры способа доставки :sendmail.

    • :location — расположение исполняемого файла sendmail. По умолчанию — /usr/sbin/sendmail.

    • :arguments — аргументы командной строки. По умолчанию — %w[ -i ]; перед отправкой сообщения автоматически добавляется -f sender@address.

  • file_settings — позволяет переопределить параметры способа доставки :file.

    • :location — каталог, в который будут записываться письма. По умолчанию используется каталог приложения tmp/mails.

  • raise_delivery_errors — следует ли генерировать ошибки, если не удалось доставить письмо.

  • delivery_method — определяет способ доставки. Возможные значения: :smtp (по умолчанию), :sendmail, :test и :file. Также можно передать пользовательский объект способа доставки, например MyOwnDeliveryMethodClass. Сведения об интерфейсе, который необходимо реализовать для пользовательского агента доставки, см. в документации гема Mail.

  • perform_deliveries — определяет, отправляет ли Action Mailer письма фактически при вызове .deliver для сообщения электронной почты или метода Action Mailer. По умолчанию отправка включена, но её можно отключить для упрощения функционального тестирования.

  • deliveries — хранит массив всех писем, отправленных через Action Mailer с помощью delivery_method :test. Наиболее полезно для модульного и функционального тестирования.

  • delivery_job — класс задачи, используемый вместе с deliver_later. Почтовые программы могут задать здесь пользовательскую задачу доставки. По умолчанию используется ActionMailer::MailDeliveryJob.

  • deliver_later_queue_name — имя очереди, используемой deliver_later со значением delivery_job по умолчанию. Почтовые программы могут задать пользовательское имя очереди.

Константы

PROTECTED_IVARS

Атрибуты

mailer_name [W]

Позволяет задать имя текущего почтового объекта.

Открытые методы класса

controller_path ()
Псевдоним для: mailer_name
default (value = nil) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 581
def default(value = nil)
  self.default_params = default_params.merge(value).freeze if value
  default_params
end

Позволяет задавать значения по умолчанию через конфигурацию приложения:

config.action_mailer.default_options = { from: "no-reply@example.org" }
Также имеет псевдоним: default_options=
default_options= (value = nil)
Псевдоним для: default
email_address_with_name (address, name) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 603
def email_address_with_name(address, name)
  Mail::Address.new.tap do |builder|
    builder.address = address
    builder.display_name = name.presence
  end.to_s
end

Возвращает адрес электронной почты в формате «Имя <email@example.com>».

Если имя — пустая строка, возвращает только адрес.

mailer_name () Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 571
def mailer_name
  @mailer_name ||= anonymous? ? "anonymous" : name.underscore
end

Возвращает имя текущего почтового объекта. Этот метод также используется в качестве пути для поиска представления. Если почтовый объект анонимный, метод вернёт вместо этого anonymous.

Также имеет псевдоним: controller_path
new () Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 639
def initialize
  super()
  @_mail_was_called = false
  @_message = Mail.new
end
Вызывает метод суперкласса
register_interceptor (interceptor) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 548
def register_interceptor(interceptor)
  Mail.register_interceptor(observer_class_for(interceptor))
end

Регистрирует перехватчик, который будет вызван перед отправкой письма. В качестве перехватчика можно передать класс, строку или символ. Если передана строка или символ, они будут преобразованы в CamelCase, а затем в константу.

register_interceptors (*interceptors) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 522
def register_interceptors(*interceptors)
  interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
end

Регистрирует один или несколько перехватчиков, которые будут вызваны перед отправкой письма.

register_observer (observer) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 534
def register_observer(observer)
  Mail.register_observer(observer_class_for(observer))
end

Регистрирует наблюдателя, который получит уведомление о доставке письма. В качестве наблюдателя можно передать класс, строку или символ. Если передана строка или символ, они будут преобразованы в CamelCase, а затем в константу.

register_observers (*observers) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 512
def register_observers(*observers)
  observers.flatten.compact.each { |observer| register_observer(observer) }
end

Регистрирует одного или нескольких наблюдателей, которые получат уведомление о доставке письма.

supports_path? () Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 938
def self.supports_path? # :doc:
  false
end

В письмах не поддерживаются ссылки с относительными путями.

unregister_interceptor (interceptor) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 555
def unregister_interceptor(interceptor)
  Mail.unregister_interceptor(observer_class_for(interceptor))
end

Отменяет регистрацию ранее зарегистрированного перехватчика. В качестве перехватчика можно передать класс, строку или символ. Если передана строка или символ, они будут преобразованы в CamelCase, а затем в константу.

unregister_interceptors (*interceptors) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 527
def unregister_interceptors(*interceptors)
  interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
end

Отменяет регистрацию одного или нескольких ранее зарегистрированных перехватчиков.

unregister_observer (observer) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 541
def unregister_observer(observer)
  Mail.unregister_observer(observer_class_for(observer))
end

Отменяет регистрацию ранее зарегистрированного наблюдателя. В качестве наблюдателя можно передать класс, строку или символ. Если передана строка или символ, они будут преобразованы в CamelCase, а затем в константу.

unregister_observers (*observers) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 517
def unregister_observers(*observers)
  observers.flatten.compact.each { |observer| unregister_observer(observer) }
end

Отменяет регистрацию одного или нескольких ранее зарегистрированных наблюдателей.

Открытые методы экземпляра

attachments () Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 756
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)
email_address_with_name (address, name) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 680
def email_address_with_name(address, name)
  self.class.email_address_with_name(address, name)
end

Возвращает адрес электронной почты в формате «Имя <email@example.com>».

Если имя — пустая строка, возвращает только адрес.

headers (args = nil) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 718
def headers(args = nil)
  if args
    @_message.headers(args)
  else
    @_message
  end
end

Позволяет передавать случайные и нестандартные заголовки новому объекту Mail::Message, который добавит их к себе.

headers['X-Special-Domain-Specific-Header'] = "SecretValue"

В headers также можно передать хеш с именами и значениями полей заголовка, которые затем будут установлены для объекта 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, чтобы сбросить текущее значение. В противном случае для того же заголовка будет добавлено ещё одно поле.

mail (headers = {}, &block) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 865
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 — адрес, который будет указан в заголовке письма 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

Метод выполнит поиск всех шаблонов с именем «welcome» в каталоге «app/views/notifier». Если шаблон welcome не найден, будет вызвана ошибка ActionView::MissingTemplate.

Однако эти параметры можно изменить:

mail(template_path: 'notifications', template_name: 'another')

Теперь будут найдены все шаблоны с именем «another» в каталоге «app/views/notifications».

Если передать блок, можно отобразить выбранные шаблоны:

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
mailer_name () Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 673
def mailer_name
  self.class.mailer_name
end

Возвращает имя объекта почтового отправителя.

Закрытые методы экземпляра

default_i18n_subject (interpolations = {}) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 932
def default_i18n_subject(interpolations = {}) # :doc:
  mailer_scope = self.class.mailer_name.tr("/", ".")
  I18n.t(:subject, **interpolations, scope: [mailer_scope, action_name], default: action_name.humanize)
end

Переводит subject с помощью класса Rails I18n в области [mailer_scope, action_name]. Если перевод subject в указанной области не найден, используется человекочитаемый вариант action_name. Если тема содержит интерполяции, их можно передать через параметр interpolations.

set_content_type (m, user_content_type, class_default) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 910
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».

Если тип содержимого не передан в заголовках и вложений нет либо сообщение является составным, используется тип содержимого по умолчанию.

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API