El componente que se encarga de los envíos de correos en Rails es Action Mailer.
El primer paso para poder enviar correos en Rails es crear un mailer.
Así como los controladores, los mailers involucran varios archivos, así que es mejor utilizar el generador que trae Rails.
Por ejemplo, para crear un mailer llamado UserMailer
que agrupe los correos que les vamos a enviar a los usuarios se utiliza el siguiente comando que crea varios archivos:
$ rails generate mailer UserMailer
create app/mailers/user_mailer.rb
invoke erb
create app/views/user_mailer
invoke test_unit
create test/mailers/user_mailer_test.rb
create test/mailers/previews/user_mailer_preview.rb
El componente principal del mailer es la clase UserMailer
que se se encuentra en el archivo app/mailers/user_mailer.rb
:
class UserMailer < ApplicationMailer
end
Cada método de la clase se va a convertir en un correo. Por ejemplo, creemos un nuevo correo de bienvenida:
class UserMailer < ApplicationMailer
def welcome_email(user)
@user = user
mail(to: @user.email, subject: 'Bienvenido a mi super sitio!')
end
end
La primera línea del método welcome_email
está creando una variable de instancia para la vista. La segunda línea renderiza y envía el correo.
Así como con los controladores, las vistas de los emails deben ir en una ubicación definida y se deben llamar igual al método.
Por ejemplo, para el método welcome_email
debemos crear un archivo llamado welcome_email.html.erb
dentro de la carpeta app/views/user_mailer/
:
<h1>Bienvenido a mi sitio <%= @user.name %></h1>
El layout por defecto se encuentra en app/views/layouts/mailer.html.erb
.
Podemos crear también una versión de texto para los clientes de correo que aún no soportan HTML (aunque la realidad es que hoy en día la mayoría soporta HTML):
Bienvenido a mi sitio <%= @user.name %>
========================================
Cuando llamas el método mail
desde welcome_controller
Action Mailer va a detectar las dos vistas (HTML y texto) y las va a enviar para que cada cliente de correo decida cuál mostrar.
Para enviar el email desde otra parte de la aplicación invocas el método sobre la clase directamente y lo envías con deliver_now
o deliver_later
. Por ejemplo:
UserMailer.welcome_email(user).deliver_later
La diferencia entre deliver_now
y deliver_later
es que este último envía el mensaje de forma asincrónica, pero para eso debes tener configurado Active Job.
En desarrollo no queremos que los emails lleguen realmente a su destino, simplemente saber que están funcionando.
La forma más fácil que hemos encontrado es con una gema llamada Letter Opener que permite visualizar los correos en el navegador.
Para configurar Letter Opener:
-
Agrega la gema al
Gemfile
:gem "letter_opener", group: :development
-
Ejecuta
bundle install
. -
Configura el modo de envío en
config/environments/development.rb
(busca la línea y asegúrate que quede como la siguiente):config.action_mailer.delivery_method = :letter_opener
Eso es todo. La próxima vez que se envíe un email se abrirá una nueva pestaña del navegador con el email.
Lo más recomendado para producción es utilizar un servicio como MailGun, Postmark, SendGrid o uno parecido.
Si vas a incluir vínculos a tu aplicación en los emails es importante que utilices los helpers que terminan en _url
en vez de _path
(es decir, root_url
en vez de root_path
) para que Action Mailer genere toda la URL al sitio.
Sin embargo, lo anterior presenta un problema y es decirle a Rails cuál es el dominio en donde va a estar alojada la aplicación.
Para eso hay varias alternativas pero quizá la más fácil sea configurar cada uno de los ambientes con el host
correspondiente.
Por ejemplo, en config/environments/development.rb
y config/environments/test.rb
:
config.action_mailer.default_url_options = { host: "localhost:3000" }
En config/environments/production.rb
:
config.action_mailer.default_url_options = { host: "midominio.com" }