Spec-Zone.ru › Ruby on Rails 7.1

класс 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 выполнит ваш метод из фонового задания.

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

Письма в формате multipart

Сообщения в формате multipart также могут использоваться неявно, потому что Action Mailer автоматически обнаружит и использует шаблоны в формате multipart, где каждый шаблон имеет имя, соответствующее имени действия, после которого следует тип содержимого. Каждый такой обнаруженный шаблон будет добавлен к сообщению в качестве отдельной части.

Например, если существуют следующие шаблоны:

  • signup_notification.text.erb

  • signup_notification.html.erb

  • signup_notification.xml.builder

  • signup_notification.yml.erb

Каждый из них будет отображен и добавлен в сообщение в качестве отдельной части с соответствующим типом содержимого. Тип содержимого для всего сообщения автоматически устанавливается на multipart/alternative, что указывает на то, что письмо содержит несколько различных представлений одного и того же тела письма. Те же переменные экземпляра, определенные в действии, передаются во все шаблоны писем.

Неявное отображение шаблонов не выполняется, если к письму были добавлены какие-либо вложения или части. Это означает, что вам необходимо вручную добавить каждую часть в письмо и установить тип содержимого письма на multipart/alternative.

Вложения

Отправка вложений в письмах проста:

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

Это приведет к (если в директории представлений есть шаблоны welcome.text.erb и welcome.html.erb) отправке полного multipart/mixed письма с двумя частями: первой частью является multipart/alternative с текстовыми и HTML-частями письма внутри, а второй частью является application/pdf с Base64-кодированной копией файла book.pdf с именем файла free_book.pdf.

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

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

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

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 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 (комбинирует механизм Challenge/Response для обмена информацией и криптографический алгоритм Message Digest 5 для хеширования важной информации)

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

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

  • 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 644
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 и затем к ней будет применено constantize.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

attachments() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 761
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 685
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 723
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 870
def mail(headers = {}, &block)
  return message if @_mail_was_called && headers.blank? && !block

  # At the beginning, do not consider class default for content_type
  content_type = headers[:content_type]

  headers = apply_defaults(headers)

  # Apply charset at the beginning so all fields are properly quoted
  message.charset = charset = headers[:charset]

  # Set configure delivery behavior
  wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options])

  assign_headers_to_message(message, headers)

  # Render the templates and blocks
  responses = collect_responses(headers, &block)
  @_mail_was_called = true

  create_parts_from_responses(message, responses)
  wrap_inline_attachments(message)

  # Set up content type, reapply charset and handle parts order
  message.content_type = set_content_type(message, content_type, headers[:content_type])
  message.charset      = charset

  if message.multipart?
    message.body.set_sort_order(headers[:parts_order])
    message.body.sort_parts!
  end

  message
end

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

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

  • :subject — тема сообщения. Если она опущена, Action Mailer запросит у класса Rails I18n переведённую :subject в контексте [mailer_scope, action_name], или, если это отсутствует, переведёт человекочитаемую версию action_name.

  • :to — получатель сообщения, может быть строкой адресов или массивом адресов.

  • :from — отправитель сообщения.

  • :cc — список копий сообщения, может быть строкой адресов или массивом адресов.

  • :bcc — список скрытых копий сообщения, может быть строкой адресов или массивом адресов.

  • :reply_to — адрес для заголовка Reply-To электронного письма.

  • :date — дата отправки электронного письма.

Вы можете установить значения по умолчанию для любого из перечисленных заголовков (кроме :date) с помощью метода класса ::default:

class Notifier < ActionMailer::Base
  default from: 'no-reply@test.lindsaar.net',
          bcc: 'email_logger@test.lindsaar.net',
          reply_to: 'bounces@test.lindsaar.net'
end

Если нужны другие заголовки, не перечисленные выше, можно передать их в хеше заголовков или использовать метод headers['name'] = value.

Если :return_path указан как заголовок, это значение будет использоваться в качестве адреса «отправителя» для сообщения Mail. Это полезно, когда уведомления об отправке необходимо отправлять на другой адрес, чем тот, который указан в :from. Mail фактически будет использовать :return_path вместо :sender в приоритете перед полем :from для значения «отправителя».

Если вы не передаёте блок методу mail, он найдёт все шаблоны в путях представления, используя по умолчанию имя малера и имя метода, из которого был вызван метод. Затем он создаст части для каждого из этих шаблонов, сделав разумные предположения о правильном типе контента и последовательности, и вернёт полностью подготовленный объект Mail::Message, готовый к вызову :deliver для отправки.

Например:

class Notifier < ActionMailer::Base
  default from: 'no-reply@test.lindsaar.net'

  def welcome
    mail(to: 'mikel@test.lindsaar.net')
  end
end

Будет искать все шаблоны в «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 678
def mailer_name
  self.class.mailer_name
end

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

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

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