Três mailers, cada um com um template HTML e um de texto

Prévia grátis 3 min de leitura

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.

Aula 1 de 7 · grátis

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.

Digite para buscar...