Três mailers, cada um com um template HTML e um de texto
Todos os mailers deste app, por inteiro
app/mailers/auth/password_mailer.rb:
module Auth
class PasswordMailer < ApplicationMailer
def reset
@user = params[:user]
@reset_url = edit_auth_password_reset_url(params[:token])
mail(to: @user.email, subject: I18n.t("auth.password_resets.mail.subject"))
end
end
end
app/mailers/partners/inquiry_mailer.rb:
module Partners
class InquiryMailer < ApplicationMailer
def new_inquiry
@inquiry = params[:inquiry]
mail(to: Rails.configuration.x.email.address, reply_to: @inquiry.email,
subject: I18n.t("partners.inquiry.mail.subject", company: @inquiry.company, tier: I18n.t("partners.tiers.#{@inquiry.tier}.name")))
end
end
end
app/mailers/notifications/notification_mailer.rb:
module Notifications
class NotificationMailer < ApplicationMailer
layout "notifications_mailer"
# One email for one or several notifications of the same kind, written
# in the recipient's language.
def notify
@recipient = params[:recipient]
notifications = params[:notifications]
kind_class = notifications.first.kind_class
::Notifications::RecipientLocale.with(@recipient) do
@content = kind_class.email_content(notifications, recipient: @recipient)
@reason = I18n.t("notifications.kinds.#{kind_class.kind}.email.reason", default: "")
@unsubscribe_url = notification_unsubscribe_url(::Notifications::UnsubscribeToken.generate(user: @recipient, key: kind_class.preference_key))
@settings_url = identity_settings_url(anchor: "notifications")
headers["List-Unsubscribe"] = "<#{@unsubscribe_url}>"
headers["List-Unsubscribe-Post"] = "List-Unsubscribe=One-Click"
mail(to: @recipient.email, subject: @content.subject)
end
end
end
end
São três mailers, o conjunto inteiro deste app. Os três herdam de ApplicationMailer, definem variáveis de instância que um template de view lê e terminam com uma única chamada a mail(...). O terceiro faz mais em volta dessa chamada: escreve o email no idioma de quem vai receber e acrescenta os cabeçalhos que um cliente de email precisa para oferecer o descadastro com um clique. Por baixo, a forma é a mesma.
ApplicationMailer, a base compartilhada
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: email_address_with_name(Rails.configuration.x.email.address, "Newbie on Rails")
layout "mailer"
end
O default from: define o remetente uma vez, e todo mailer o herda sem repetir. O endereço vem de uma configuração só, o config.x.email.address do config/application.rb, que lê ENV.fetch("APP_EMAIL", "[email protected]"). O InquiryMailer envia para essa mesma configuração, então o remetente e a caixa que recebe as propostas de parceiros não têm como se desencontrar. O email_address_with_name é um helper do Action Mailer que monta Newbie on Rails <[email protected]> e põe o nome entre aspas quando precisa.
O layout "mailer" é o mesmo mecanismo de nível de classe que o curso Namespacing de layout cobriu para controllers, declarado num mailer. O NotificationMailer troca esse layout com layout "notifications_mailer", do jeito que um controller pode trocar o layout do pai.
Um template HTML e um de texto puro por mailer
O find app/views -path "*mailer*" -type f lista dez arquivos. Seis são templates por action: password_mailer/reset.html.erb, password_mailer/reset.text.erb, inquiry_mailer/new_inquiry.html.erb, inquiry_mailer/new_inquiry.text.erb, notification_mailer/notify.html.erb e notification_mailer/notify.text.erb. Os outros quatro são layouts, em pares: layouts/mailer.html.erb e layouts/mailer.text.erb, compartilhados pelos dois primeiros mailers, e layouts/notifications_mailer.html.erb e layouts/notifications_mailer.text.erb para o terceiro.
Cada action de mailer chama mail(...) sem argumento format:. A convenção do Action Mailer acha os dois arquivos pelo nome e envia um email multipart: HTML para o cliente que o renderiza, e texto puro como alternativa para o que não renderiza. Nenhum arquivo de mailer pede isso explicitamente.
O que este curso cobre
Sete aulas, cada uma checada contra os três mailers deste app e a configuração instalada de jobs e filas. Esta aula trata da configuração multipart. A aula 2 trata do padrão parametrizado .with(...), com params[:user] e params[:token] lendo os valores de volta dentro da action. A aula 3 trata do default_url_options, definido de um jeito por ambiente, que deixa um mailer montar uma URL absoluta sem requisição por trás. A aula 4 trata de deliver_later contra deliver_now, e de onde este app usa cada um, achado com um grep. A aula 5 trata do Solid Queue, um backend de jobs durável, apoiado em banco, com banco próprio em desenvolvimento e teste. A aula 6 trata do config/recurring.yml, o recurso de tarefas agendadas do Solid Queue, que já roda três tarefas em produção.
Continue com a aula 2
with(...): como este app passa dados pra um mailer
Como o .with(...) transforma argumentos nomeados num hash params, e por que chamadas por posição falham nessas actions.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.