Spec-Zone.ru › Ruby on Rails 7.2

класс 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 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-кодированной копией книги file.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 экземпляр.

Хэш по умолчанию

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 для настройки ваших сообщений и используя 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 в Action Mailer реализованы с помощью AbstractController::Callbacks, поэтому вы можете определять и настраивать обработчики аналогичным образом, как вы используете обработчики в классах, которые наследуются от ActionController::Base.

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

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

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, так и с логгерами Log4r.

  • smtp_settings - Разрешает подробную настройку метода доставки :smtp:

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

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

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

    • :user_name - Если ваш почтовый сервер требует аутентификации, задайте имя пользователя в этом параметре.

    • :password - Если ваш почтовый сервер требует аутентификации, задайте пароль в этом параметре.

    • :authentication - Если ваш почтовый сервер требует аутентификации, укажите здесь тип аутентификации. Это символ, и он может быть одним из :plain (пароль будет отправлен в кодировке Base64), :login (пароль будет отправлен в кодировке Base64) или :cram_md5 (комбинирует механизм «запрос/ответ» для обмена информацией и криптографический алгоритм 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/TLS (SMTPS: SMTP через прямое TLS-соединение) для SMTP-соединения.

    • :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 582
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=

Также псевдоним: default_options=
default_options=(value = nil)

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

config.action_mailer.default_options = { from: "no-reply@example.org" }
Псевдоним для: default
email_address_with_name(address, name) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 607
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 570
def mailer_name
  @mailer_name ||= anonymous? ? "anonymous" : name.underscore
end

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

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

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

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

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

END_OF_DOCUMENT_MARKER

Методы публичного экземпляра

attachments() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 760
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 684
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 722
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, чтобы сбросить значение, иначе будет добавлено ещё одно поле для того же заголовка.

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

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

Приватные методы экземпляра

default_i18n_subject(interpolations = {}) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 936
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.

set_content_type(m, user_content_type, class_default) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 914
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–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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