Spec-Zone.ru › Ruby on Rails 4.2

класс ActionMailer::Base

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

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

Модели Mailer

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

$ rails generate mailer Notifier

Сгенерированная модель наследуется от ApplicationMailer, которая, в свою очередь, наследуется от ActionMailer::Base. Модель mailer определяет методы, используемые для генерации электронного сообщения. В этих методах можно настраивать переменные, используемые в представлениях mailer, параметры самого письма, такие как адрес :from, и вложения.

class ApplicationMailer < ActionMailer::Base
  default from: 'from@exmaple.com'
  layout 'mailer'
end

class Notifier < 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

Внутри метода mailer у вас есть доступ к следующим методам:

  • 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

Представления Mailer

Как и Action Controller, каждый класс mailer имеет соответствующую директорию представлений, в которой каждый метод класса ищет шаблон с его именем.

Для определения шаблона, используемого с рассылкой, создайте файл .erb с тем же именем, что и метод в вашей модели mailer. Например, в определенной выше модели mailer шаблон в app/views/notifier/welcome.text.erb будет использоваться для генерации электронного письма.

Переменные, определенные в методах вашей модели mailer, доступны как переменные экземпляра в соответствующих представлениях.

По умолчанию письма отправляются в формате простого текста, поэтому пример представления для нашей модели может выглядеть так:

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-адреса можно генерировать в представлениях mailer, используя url_for или именованные маршруты. В отличие от контроллеров из Action Pack, экземпляр mailer не имеет никакого контекста о входящем запросе, поэтому вам нужно предоставить все необходимые детали для генерации 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-адресе для определения относительного пути.

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

config.action_mailer.default_url_options = { host: "example.com" }

Когда вы решите установить значение по умолчанию :host для своих mailers, вам необходимо убедиться, что вы используете опцию only_path: false при использовании url_for. Поскольку помощник представления url_for по умолчанию генерирует относительные URL-адреса, когда опция :host не указана явно, передача only_path: false гарантирует генерацию абсолютных URL-адресов.

Отправка письма

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

Notifier.welcome(User.first).deliver_now # sends the email
mail = Notifier.welcome(User.first)      # => an ActionMailer::MessageDelivery object
mail.deliver_now                    # sends the email

Класс ActionMailer::MessageDelivery является оболочкой вокруг объекта Mail::Message. Если вам нужен прямой доступ к объекту Mail::Message, вы можете вызвать метод message на объекте ActionMailer::MessageDelivery.

Notifier.welcome(User.first).message     # => a Mail::Message object

Action Mailer хорошо интегрирован с Active Job, поэтому вы можете отправлять электронные письма в фоновом режиме (например, вне цикла запроса-ответа, чтобы пользователь не должен был ждать):

Notifier.welcome(User.first).deliver_later # enqueue the email sending to Active Job

Вы никогда не создаёте экземпляр класса mailer. Вместо этого, вы просто вызываете метод, который вы определили для самого класса.

Письма с несколькими частями

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

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

  • signup_notification.text.erb

  • signup_notification.html.erb

  • signup_notification.xml.builder

  • signup_notification.yml.erb

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

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

Вложения

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

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

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

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

Значение Hash по умолчанию

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

class Notifier < 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 Notifier < ApplicationMailer
  default 'Content-Transfer-Encoding' => '7bit',
          content_description: 'This is a description'
end

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

class Notifier < ApplicationMailer
  default 'X-Special-Header' => Proc.new { my_method }

  private

    def my_method
      'some complex call'
    end
end

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

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

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

Обработчики

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

class Notifier < 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, чтобы заголовки были обработаны правильно.

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

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

class NotifierPreview < ActionMailer::Preview
  def welcome
    Notifier.welcome(User.first)
  end
end

Методы должны возвращать объект Mail::Message, который можно сгенерировать, вызвав метод mailer без дополнительных deliver_now / deliver_later. Путь к каталогу с предварительными просмотрами mailer можно настроить с помощью опции 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 - На случай, если ваш почтовый сервер не работает на порту 25, вы можете изменить его.

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

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

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

    • :authentication - Если ваш почтовый сервер требует аутентификации, укажите здесь тип аутентификации. Это символ, и один из :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', 'client_once', 'fail_if_no_peer_cert') или напрямую константу (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER, …).

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

    • :location - Путь к исполняемому файлу sendmail. По умолчанию /usr/sbin/sendmail.

    • :arguments - Аргументы командной строки. По умолчанию -i -t с -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. Наиболее полезно для модульного и функционального тестирования.

Константы

PROTECTED_IVARS

Атрибуты

mailer_name[W]

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

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

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

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

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

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

Вызывает метод суперкласса
receive(raw_mail) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 526
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 479
def register_interceptor(interceptor)
  delivery_interceptor = case interceptor
    when String, Symbol
      interceptor.to_s.camelize.constantize
    else
      interceptor
    end

  Mail.register_interceptor(delivery_interceptor)
end

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

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

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

register_observer(observer) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 465
def register_observer(observer)
  delivery_observer = case observer
    when String, Symbol
      observer.to_s.camelize.constantize
    else
      observer
    end

  Mail.register_observer(delivery_observer)
end

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

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

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

Защищённые методы класса

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

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

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

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

  m = @_message

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

  # Call all the procs (if any)
  default_values = {}
  self.class.default.each do |k,v|
    default_values[k] = v.is_a?(Proc) ? instance_eval(&v) : v
  end

  # Handle defaults
  headers = headers.reverse_merge(default_values)
  headers[:subject] ||= default_i18n_subject

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

  # Set configure delivery behavior
  wrap_delivery_behavior!(headers.delete(:delivery_method), headers.delete(:delivery_method_options))

  # Assign all headers except parts_order, content_type and body
  assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
  assignable.each { |k, v| m[k] = v }

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

  create_parts_from_responses(m, responses)

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

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

  m
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 и 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 615
def mailer_name
  self.class.mailer_name
end

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

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

default_i18n_subject(interpolations = {}) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 879
def default_i18n_subject(interpolations = {})
  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 857
def set_content_type(m, user_content_type, class_default)
  params = m.content_type_parameters || {}
  case
  when user_content_type.present?
    user_content_type
  when m.has_attachments?
    if m.attachments.detect { |a| a.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