Enviando E-mails de Confirmação de Pedido no Rails com ActionMailer - Parte 1

Enviando E-mails de Confirmação de Pedido no Rails com ActionMailer - Parte 1
Photo by Tiffany Tertipes / Unsplash

Enviar e-mails é uma funcionalidade comum em aplicações web. No Ruby on Rails, o ActionMailer é uma ferramenta poderosa para lidar com o envio de e-mails. Vamos explorar como utilizá-lo para enviar e-mails de confirmação de pedidos e como testar essa funcionalidade.

Informações básicas

Configuração do Ambiente de Testes

  1. Adicione as gems necessárias ao seu Gemfile:
group :development, :test do
 gem 'rspec-rails'
 gem 'shoulda-matchers'
 gem 'email_spec'
 gem 'letter_opener'
end
  1. Execute bundle install.
  2. Configure o RSpec e o Shoulda Matchers em spec/rails_helper.rb:
require 'email_spec'
require 'email_spec/rspec'

RSpec.configure do |config|
 config.include(EmailSpec::Helpers)
 config.include(EmailSpec::Matchers)
end

Shoulda::Matchers.configure do |config|
 config.integrate do |with|
   with.test_framework :rspec
   with.library :rails
 end
end

Configuração do Ambiente de Desenvolvimento

  1. Em config/environments/development.rb, configure o letter_opener:
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

  1. config.action_mailer.delivery_method = :letter_openerEsta linha define o método de entrega dos e-mails para :letter_opener. O Letter Opener é uma gem usada principalmente em ambientes de desenvolvimento para visualizar e-mails enviados pela aplicação sem a necessidade de enviá-los realmente através de um serviço SMTP. Quando um e-mail é enviado, o Letter Opener abre uma nova aba no navegador padrão exibindo o conteúdo do e-mail. Isso é útil para desenvolvedores testarem e visualizarem e-mails durante o desenvolvimento.
  2. config.action_mailer.perform_deliveries = trueEsta configuração determina se os e-mails serão realmente enviados. Quando definido como true, o ActionMailer tentará enviar e-mails. Se definido como false, o ActionMailer não enviará e-mails, mas irá simular o envio. Isso pode ser útil em certos ambientes (como testes) onde você não quer que os e-mails sejam realmente enviados.
  3. config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }Esta linha define as opções padrão de URL para o ActionMailer. O host e a port especificados aqui são usados para gerar URLs completas nos e-mails, como links para redefinição de senha ou confirmação de conta. No exemplo dado, o host está definido como localhost e a porta como 3000, que são os valores padrão para um servidor Rails em desenvolvimento. Isso significa que qualquer link gerado nos e-mails apontará para http://localhost:3000. Em um ambiente de produção, você substituiria esses valores pelo domínio real e pela porta (se aplicável) do seu aplicativo.

Criando o Mailer com ActionMailer

  1. Gere o Mailer:
rails g mailer OrderMailer
  1. Defina o método de envio no app/mailers/order_mailer.rb:
class OrderMailer < ApplicationMailer
 def order_confirmation(user, order)
   @user = user
   @order = order
   mail(to: @user.email, subject: 'Order Confirmation')
 end
end

Criando a View do Mailer

  1. Crie app/views/order_mailer/order_confirmation.html.erb.
<!DOCTYPE html>
<html>
<head>
  <title>Order Confirmation</title>
</head>
<body>
  <h1>Order Confirmation</h1>
  <p>
    Hello <%= @user.name %>,
  </p>
  <p>
    Thank you for your order. We are currently processing your order and will send you a confirmation once it is shipped.
  </p>
  <p>
    Order Details:
    <% @order.items.each do |item| %>
      <div>
        <%= item.name %> - <%= item.quantity %>
      </div>
    <% end %>
  </p>
  <p>
    If you have any questions, please contact us at [email protected].
  </p>
</body>
</html>

Neste exemplo, a view do e-mail inclui uma saudação personalizada com o nome do usuário e uma mensagem de agradecimento, que são os requisitos dos nossos testes. Além disso, adicionei detalhes do pedido e informações de contato para tornar o e-mail mais informativo e útil para o usuário.

Nota: Certifique-se de que as variáveis @user e @order estejam sendo corretamente definidas no método order_confirmation do seu OrderMailer. Por exemplo:

Escrevendo Testes

  1. Crie spec/mailers/order_mailer_spec.rb para testar o mailer.
require "rails_helper"

RSpec.describe OrderMailer, type: :mailer do
  let(:user) { create(:user) }
  let(:order) { create(:order, user: user) }

  describe 'order_confirmation' do
    let(:mail) { OrderMailer.order_confirmation(user, order) }

    it 'renders the headers' do
      expect(mail.subject).to eq('Order Confirmation')
      expect(mail.to).to eq([user.email])
      expect(mail.from).to eq(['[email protected]'])
    end

    it 'renders the body' do
      expect(mail.body.encoded).to match("Hello #{user.name},")
      expect(mail.body.encoded).to match("Thank you for your order.")
    end
  end
end

OrderMailer Spec

  • Testa se o assunto, destinatário e remetente do e-mail estão corretos.
  • Verifica se o corpo do e-mail contém as informações esperadas.

Enviando o E-mail na Aplicação

  1. No ponto da aplicação onde o pedido é finalizado, adicione:
OrderMailer.order_confirmation(user, order).deliver_later

Diferença entre usar e não usar ActionMailer

O ActionMailer é uma parte integrante do Rails que simplifica o envio de e-mails. Sem ele, você teria que manualmente configurar SMTP, lidar com a renderização de templates e gerenciar a lógica de envio. Com ActionMailer, você obtém:

  • Integração fácil com templates de e-mail.
  • Gerenciamento simplificado de configurações de envio.
  • Suporte para envio assíncrono e sincronizado.
  • Facilidade para testar e-mails.

O ActionMailer é uma ferramenta essencial no Rails para o envio de e-mails, simplificando o processo e permitindo que você se concentre mais na lógica do negócio e menos na infraestrutura de envio de e-mails. Este post cobriu como configurar, enviar e testar e-mails de confirmação de pedidos usando ActionMailer.

Porém, há algo que precisamos melhorar! Pensa comigo, é importante que o usuário receba o email imediantamente? ou essa operação poderia tranquilamente levar alguns segundos ou até 2 minutos mais ou menos, o que pensa? É isso que precisamos melhorar.

Referências

Documentação oficial do ActionMailer: Action Mailer Basics

Read more