Formulario de contacto en RoR con Action Mailer
Edito y amplío este post del 12 de diciembre del 2006 para intentar que el ejemplo sea más claro. Está probado en Rails 1.2.
localhost:~ User$ ./script/generate mailer Contact
Añadir al final del archivo config/environment.rb lo siguiente para que Action Mailer pueda autentificarse y enviar el correo.
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => 'smtp.website.com',
:port => 25,
:authentication => :login, # Don't change this one.
:user_name => "smtp_username",
:password => "smtp_password"}
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.default_charset = "utf-8"
Se puede enviar también utilizando sendmail poniendo únicamente
ActionMailer::Base.delivery_method = :sendmail
Ahora edita el archivo app/models/contact.rb y añade el método que enviará el email:
class Contact < ActionMailer::Base
def contact_email(email_params, sent_at = Time.now)
@recipients = "contact@website.co.uk" # Dirección donde se envía el correo
@from = email_params[:name] + " <" + email_params[:address] + ">"
@subject = email_params[:subject]
@sent_on = sent_at
@body["email_body"] = email_params[:body]
@body["email_name"] = email_params[:name]
end
end
En el directorio ‘views/contact’ crea el archivo contact_email.rhtml, este archivo es el contenido del email que se enviará a la dirección especificada anteriormente. En este caso se envían las variables “name” y “body”. Dentro de este archivo se puede poner texto y otras variables o incluso definirlo como html con las cabeceras correspondientes.
Name:
<%= @email_name %>
Message:
<%= @email_body %>
Vamos a crear el formulario de contacto. Crea una vista en el controlador principal, por ejemplo contacto.rhtml:
<%= start_form_tag :action=> "send_mail" %>
<label for="email_name">Name:</label>
<%= text_field "email", "name", :size => 30 %>
<label for="email_address">Email Address:</label>
<%= text_field "email", "address", :size => 30 %>
<label for="email_subject">Subject:</label>
<%= text_field "email", "subject", :size => 30 %>
<label for="email_body">Body:</label>
<%= text_area "email", "body", :rows => 8, :cols => 30 %>
<input value="Send Email" class="primary" type="submit" />
<%= end_form_tag %>
En el controlador principal añade el método siguiente que es el que procesa el formulario
def send_mail
Contact::deliver_contact_email(@params[:email])
end
Hay un detalle importante: el nombre del método que se llama es deliver_contact_email, en el modelo el método se llama contact_email. Cuando se llama a un método que envía un email con ActionMailer hay que seguir esta convención y añadir “deliver” antes del nombre del método.
Siguiendo este ejemplo podemos tener otro método que envía otro email que se llame contact_email_factory. Cuando lo invoquemos desde el controlador habrá que hacerlo con Contact::deliver_contact_email_factory(@params[:email])
Sólo nos queda añadir un enlace para poder acceder al formulario. En la página que queramos ponemos el siguiente enlace:
<%= link_to 'Contacto', :controller => "controlador_principal", :action => "contacto" %>
En el controlador principal tiene que haber un método cómo este que es el que procesa el enlace y muestra la vista correspondiente:
def contacto
render :action => 'contacto'
end
10 Comentarios »
Redifusión RSS de los comentarios de la entrada.

He hecho lo que ponías y en el log veo perfectamente la salida, pero no envía
nada… :(
¿Sabrías pq puede ser?
environment.rb (al final)
————————–
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.default_charset = “ISO-8859-1″
contact.rb
—————–
class Contact < ActionMailer::Base
def contact_email(email_params, sent_at = Time.now)
@recipients = “xxxxxxx@gmail.com” # Dirección donde se envía el
correo
@from = email_params[:name] + ” ”
@subject = email_params[:subject]
@sent_on = sent_at
@body[”email_body”] = email_params[:body]
@body[”email_name”] = email_params[:name]
end
end
contact_email.rhtml
———————-
Nombre:
Mensaje:
resultado.rhmtl
———————
[…]
’send_mail’ %>
Nombre:
30 %>
E-mail:
30 %>
Motivo del contacto:
30 %>
Mensaje:
3, :cols => 30 %>
[…]
controlador
————-
def send_mail
Contact::deliver_contact_email(@params[:email])
render :action => ‘resultado’
end
Log
————————-
Sent mail:
Date: Mon, 22 Oct 2007 19:11:31 +0200
From: nombre
To: xxxxxxxxxxx@gmail.com
Subject: motivo
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Nombre:
nombre
Mensaje:
mensaje
Rendering actionresultadolayoutfalse within
layouts/establishment_contents
Muchas gracias.
Hola David. ¿Tienes instalado algún servidor de correo en la máquina donde estás haciendo las pruebas?, de ser así, ¿tienes el enlace simbolico al comando “sendmail” creado?
Hola. No tengo ningún servidor de correo. Pensé que con ActionMailer::Base.delivery_method = :sendmail en el environment.rb era suficiente. La llamada a send_mail lo tengo en el formulario de resultado.rhtml.
” ’send_mail’ %>”
Nombre:
30 %>
E-mail:
30 %>
Motivo del contacto:
30 %>
Mensaje:
3, :cols => 30 %>
Muchas gracias
’send_mail’ %>
Nombre:
30 %>
E-mail:
30 %>
Motivo del contacto:
30 %>
Mensaje:
3, :cols => 30 %>
</p
” ’send_mail’ %>
Nombre:
30 %>
E-mail:
30 %>
Motivo del contacto:
30 %>
Mensaje:
3, :cols => 30 %>
“
Perdona por los mensajes. Se corta cuando meto código…
“form_tag :action=> ’send_mail’”
[..]
“image_submit_tag (’../images/aceptar.gif’)”
[..]
“end_form_tag”
Lo sé David, tengo que arreglarlo de alguna manera.
El problema que tienes es que no tienes un servidor de correo que pueda enviarte los mensajes. Tendrás que subir la aplicación al servidor y probarlo on-line.
Gracias amigo :)
Gracias por tu articulo.
Emili, en :address puedo poner la ip del servidor de correo que es exchage2003 sin agregar el prefijo smtp, ej: :smtp => “smtp.10.3.240.241″, sigo todos los pasos y no me da, claro que sospecho del proxy de la empresa. gracias
En teoría debería funcionar también con la IP, sin el smtp delante. En cuanto al proxy, si lo pruebas desde tu máquina es como si tu cliente de correo estuviera enviando un email o sea que debería funcionar. Mira los logs, tal vez encuentre más información de lo que está pasando (/log/development.log). Otra cosa que puedes probar para ver si es el proxy es ejecutar tu aplicación y enviar un correo en otra red: en tu casa o en un cybercafe.
Suerte.