Spec-Zone.ru › Ruby on Rails 5.2

класс ActionMailer::Base

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

Action Mailer позволяет отправлять электронные письма из вашего приложения, используя модель отправителя и представления.

Модели отправителей

Для использования Action Mailer необходимо создать модель отправителя.

$ 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.

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

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 шаблоном, в этом случае вам необходимо добавить тело, вложения и пользовательский тип содержимого так:

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

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 на работающем экземпляре сервера разработки.

Предварительные просмотры также можно перехватить аналогичным образом, как и доставки, зарегистрировав обработчик предварительных просмотров, имеющий метод 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 (объединяет механизм «Вызов/Ответ» для обмена информацией и алгоритм криптографического «Message Digest» 5 для хэширования важной информации)

    • :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-соединение)

  • 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. См. документацию Mail-gem по интерфейсу, который нужно реализовать для пользовательского агента доставки.

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

  • deliveries - Сохраняет массив всех отправленных писем через Action Mailer с delivery_method :test. Очень полезно для модульных и функциональных тестов.

  • deliver_later_queue_name - Имя очереди, используемой с deliver_later. Значение по умолчанию mailers.

Константы

PROTECTED_IVARS

Атрибуты

mailer_name[W]

Позволяет установить имя текущего рассыльщика.

Публичные методы класса

controller_path()
Псевдоним для: mailer_name
default(value = nil) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 521
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
mailer_name() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 509
def mailer_name
  @mailer_name ||= anonymous? ? "anonymous" : name.underscore
end

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

Также имеет псевдоним: controller_path
new() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 593
def initialize
  super()
  @_mail_was_called = false
  @_message = Mail.new
end
Вызывает метод суперкласса
receive(raw_mail) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 543
def receive(raw_mail)
  ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
    mail = Mail.new(raw_mail)
    set_payload_for_mail(payload, mail)
    new.receive(mail)
  end
end

Получает исходный e-mail, парсит его в объект e-mail, декодирует его, инициализирует новый рассыльщик и передает объект e-mail методу receive объекта рассыльщика.

Если вы хотите, чтобы ваш рассыльщик мог обрабатывать входящие сообщения, вам необходимо реализовать метод receive, который принимает строку исходного e-mail в качестве параметра:

class MyMailer < ActionMailer::Base
  def receive(mail)
    # ...
  end
end
register_interceptor(interceptor) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 493
def register_interceptor(interceptor)
  Mail.register_interceptor(observer_class_for(interceptor))
end

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

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

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

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

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

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

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

Приватные методы класса

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

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

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

attachments() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 702
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)
headers(args = nil) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 664
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 811
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)

  # Setup 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

Основной метод, который создаёт сообщение и рендерит шаблоны электронных писем. Этот метод можно вызвать двумя способами: с блоком или без него.

Он принимает хэш headers. Этот хэш позволяет указать наиболее используемые заголовки в электронном сообщении, это:

  • :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 или использовать метод 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 частями.

Синтаксис блока также позволяет настраивать заголовки частей по желанию:

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 626
def mailer_name
  self.class.mailer_name
end

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

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

default_i18n_subject(interpolations = {}) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 878
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 856
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.detect(&: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–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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