Spec-Zone.ru › Ruby on Rails 5.1

класс 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

Это приведет к отправке полного multipart/mixed электронного письма с двумя частями, первой частью будет multipart/alternative с текстовыми и HTML-частями электронного письма внутри, а второй — application/pdf с кодированным в Base64 изображением файла book.pdf с именем файла free_book.pdf.

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

class NotifierMailer < ApplicationMailer
  def welcome(recipient)
    attachments['free_book.pdf'] = File.read('path/to/file.pdf')
    mail(to: recipient, subject: "New account information", body: "")
  end
end

Вы также можете отправить вложения с шаблоном html. В этом случае необходимо добавить body, вложения и настроить тип содержимого, как показано ниже:

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

Поскольку мы используем метод Action View's image_tag, вы можете передать любые другие параметры, которые вам нужны:

<h1>Please Don't Cringe</h1>

<%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>

Наблюдение и перехват почты

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

Класс наблюдателя должен реализовать метод :delivered_email(message), который будет вызван один раз для каждого отправленного письма после отправки электронного письма.

Класс перехватчика должен реализовать метод :delivering_email(message), который будет вызван перед отправкой письма, позволяя внести изменения в письмо перед отправкой в агенты доставки. Ваш класс должен внести необходимые изменения непосредственно в переданный экземпляр Mail::Message.

Параметры Hash по умолчанию

Action Mailer предоставляет некоторые разумные значения по умолчанию для ваших электронных писем, которые обычно задаются в методе по умолчанию внутри определения класса:

class NotifierMailer < ApplicationMailer
  default sender: 'system@example.com'
end

Вы можете передать любое значение заголовка, которое принимает Mail::Message. Из коробки, ActionMailer::Base задаёт следующие значения:

  • mime_version: "1.0"

  • charset: "UTF-8"

  • content_type: "text/plain"

  • parts_order: [ "text/plain", "text/enriched", "text/html" ]

parts_order и charset на самом деле не являются допустимыми полями заголовков Mail::Message, но Action Mailer корректно их переводит и устанавливает правильные значения.

Поскольку вы можете передать любое значение заголовка, вам нужно либо привести заголовок к строке, либо передать его как подчёркнутое символьное имя, поэтому следующие варианты будут работать:

class NotifierMailer < ApplicationMailer
  default 'Content-Transfer-Encoding' => '7bit',
          content_description: 'This is a description'
end

Наконец, Action Mailer также поддерживает передачу объектов Proc и Lambda в хэш по умолчанию, поэтому вы можете определять методы, которые оцениваются при генерации сообщения:

class NotifierMailer < ApplicationMailer
  default 'X-Special-Header' => Proc.new { my_method }, to: -> { @inviter.email_address }

  private
    def my_method
      'some complex call'
    end
end

Обратите внимание, что процедура/лямбда оценивается в самом начале генерации электронного письма, поэтому если вы установите что-то в хэше по умолчанию с помощью процедуры, а затем установите то же самое внутри вашего метода почтового сообщения, метод почтового сообщения перепишет это значение.

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

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

Обработчики

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

class NotifierMailer < ApplicationMailer
  before_action :add_inline_attachment!

  def welcome
    mail
  end

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

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

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

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

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

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

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

config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"

Обзор всех предварительных просмотров доступен по адресу http://localhost:3000/rails/mailers на запущенном экземпляре сервера разработки.

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

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

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

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

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

    • :authentication - Если ваш SMTP-сервер требует аутентификации, укажите тип аутентификации здесь. Это символ, и он должен быть одним из :plain (пароль будет отправлен в кодировке Base64), :login (пароль будет отправлен в кодировке Base64) или :cram_md5 (сочетает механизм Challenge/Response для обмена информацией и алгоритм криптографического дайджеста 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 519
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 507
def mailer_name
  @mailer_name ||= anonymous? ? "anonymous" : name.underscore
end

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

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

Создаёт новый объект почтового отправления. Если method_name не nil, почтовое отправление будет инициализировано в соответствии с названным методом. В противном случае, почтовое отправление останется неинициализированным (полезно, когда вам нужно только вызвать метод «receive», например).

Вызывает метод суперкласса
receive(raw_mail) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 541
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

Принимает сырое электронное письмо, анализирует его в объект письма, декодирует его, создаёт новый объект почтового отправления и передаёт объект письма в метод receive объекта почтового отправления.

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

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

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

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

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

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

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

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

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

Методы приватного класса

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

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

Общедоступные методы экземпляров

attachments() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 704
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 666
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 813
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

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

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

  • :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 628
def mailer_name
  self.class.mailer_name
end

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

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

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