Enviando Emails via STMP (Gmail) com Action Mailer do Rails - Formulário de Contato e Model sem Tabela
Fala galera, beleza? Hoje venho mostrar como enviar emails via SMTP (Gmail) com Ruby on Rails (3.2.8) através do Action Mailer e para isso estarei criando um formulário de contato com model (para desfrutarmos das validações e outros recursos) sem tabela (tableless model) como exemplo.
Gerando o Formulário com Scaffold
Formulários de contato são constituídos por campos que quando preenchidos são enviados para uma url e executam algo certo?
Então para agilizar irei gerar um scaffold com os dados que preciso e depois removerei os códigos desnecessários.
rails g scaffold Contact name:string email:string subject:string message:text
Model sem Tabela (tableless model)
Olhe para o model Contact
que acabamos de criar e ele deve estar como abaixo:
class Contact < ActiveRecord::Base
attr_accessible :email, :message, :name, :subject
end
Observe que ele herda da classe ActiveRecord
, mas como não iremos usar tabela, vamos fazer algumas mudanças..
- Primeiro vamos retirar a herança do
ActiveRecord
pois não usaremos nenhum recurso de banco de dados - Vamos incluir e extender algumas classes necessárias
- Criar dois métodos necessários para a utilização do model sem tabela
- Definir métodos acessores
Feito as mudanças, nosso model deve se parecer com esse:
class Contact
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :subject, :message, :email
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
Removendo o Desnecessário
Como não iremos precisar das funcionalidades de atualização (edição), visualização, listagem e exclusão vamos remover elas. Exclua as views index
, edit
e show
da pasta views/contacts
, remova as respectivas actions do contacts_controller.rb
e mais algumas coisas que não serão necessárias. Nosso controller fica assim por enquanto:
class ContactsController < ApplicationController
def new
@contact = Contact.new
end
def create
@contact = Contact.new(params[:contact])
if @contact.valid?
redirect_to :action => 'new'
return
end
render :action => 'new'
end
end
Repare que uma das alterações que fizemos foi trocar o .save
para .valid?
da action create
, isso serve para validar com o model antes de enviarmos o email com dados do contato.
Criando um Mailer
Vamos criar um mailer que será reponsável por determinar o template e alterar algumas opções. Execute o comando abaixo no terminal na pasta do projeto:
rails generate mailer ContactMailer
Dentro da pasta app/mailers
foi criado um arquivo chamado contact_mailer.rb
, usaremos ele para definir algumas opções do envio.
Vamos criar um método chamado contact_message
que enviará as mensagens de contato:
class ContactMailer < ActionMailer::Base
default :from => 'email_remetente@gmail.com'
def contact_message(contact)
@contact = contact
mail(:to => 'destinatario@provedor.com', :subject => 'Mensagem de Contato')
end
end
Aqui definimos o remetente, destinatário e assunto da mensagem além de passarmos os dados de contato para a view.
Criando as Views do Mailer
Crie um arquivo chamado contact_message.html.erb
e outro contact_message.text.erb
em app/views/contact_mailer/
para termos as views HTML e texto respectivamente para nosso mailer, esses arquivos conterão a mensagem propriamente. Minha view HTML ficou assim:
<h1>Mensagem de contato</h1>
<h2>Data de envio: <%= Time.now.strftime("%d/%m/%Y %H:%M") %></h2>
<p><strong>Visitante: </strong><%= @contact['name'] %></p>
<p><strong>Email: </strong><%= @contact['email'] %></p>
<% if @contact['subject'].present? %>
<p><strong>Assunto: </strong><%= @contact['subject'] %></p>
<% end %>
<p><strong>Mensagem:</strong></p>
<p><%= @contact['message'] %></p>
Definindo Configurações SMTP
Para enviarmos as mensagens via SMTP, precisamos informar os dados que serão utilizados, para isso abra o arquivo de configuração da aplicação (application.rb
) e defina as configurações do Gmail como abaixo (preenchendo com os dados do remetente):
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => 'gmail.com',
:user_name => 'usuario_remetente',
:password => 'senha123',
:authentication => 'plain',
:enable_starttls_auto => true
}
# Para debug apenas, é melhor que a linha abaixo seja adicionado apenas no ambiente de desenvolvimento
config.action_mailer.raise_delivery_errors = true
config/environmentes
, no caso acima defino uma para todos.Enviando Emails
Agora só precisamos adicionar a chamada do método responsável por enviar emails (linha 10) em nosso controller, veja como fica:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ContactsController < ApplicationController
def new
@contact = Contact.new
end
def create
@contact = Contact.new(params[:contact])
if @contact.valid?
ContactMailer.contact_message(params[:contact]).deliver
flash[:notice] = 'Mensagem enviado com sucesso'
redirect_to :action => 'new'
return
end
render :action => 'mew'
end
end
O envio já está funcionando, faça um teste!
Adicionando Validações
Vamos adicionar algumas validações no formulário, para isso abro o model Contact
e adiciono algumas linhas, ficando como abaixo:
class Contact
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :subject, :message, :email
validates :name,
:length => {:in => 2..50}
validates :email,
:format => { :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i }
validates :message,
:length => {:in => 10..750}
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
Agora se alguém tentar submeter o formulário vazio não conseguirá..

Pronto, temos nosso formulário de contato com validação e envio de emails por SMTP funcionando.
Por hoje é só pessoal, o que vocês acharam?
Até mais.