Skip to content

Instantly share code, notes, and snippets.

@wrburgess
Created November 3, 2011 21:49
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wrburgess/1337891 to your computer and use it in GitHub Desktop.
Save wrburgess/1337891 to your computer and use it in GitHub Desktop.
Rails Contact Form w/ Gmail SMTP
# Majority of this solution was written and posted here:
# http://matharvard.ca/posts/2011/aug/22/contact-form-in-rails-3
# http://railscasts.com/episodes/206-action-mailer-in-rails-3
# config/initializers/smtp_settings.rb
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "example.com",
:user_name => "test@example.com",
:password => "secret",
:authentication => "plain",
:enable_starttls_auto => true
}
#create a message class in file app/models/message.rb
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :subject, :body
validates :name, :email, :subject, :body, :presence => true
validates :email, :format => { :with => %r{.+@.+\..+} }, :allow_blank => true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
# run rails g mailer ContactMailer
# creates file called app/mailers/contact_mailer.rb
class ContactMailer< ActionMailer::Base
default :from => "noreply@youdomain.dev"
default :to => "you@youremail.dev"
def new_message(message)
@message = message
mail(:subject => "#{message.subject}")
end
end
# create the file app/views/notifications_mailer/new_message.text.erb
Name: <%= @message.name %>
Email: <%= @message.email %>
Subject: <%= @message.subject %>
Body: <%= @message.body %>
# Run rails g controller contact and then open app/controllers/contact_controller.rb
class ContactController < ApplicationController
def new
@message = Message.new
end
def create
@message = Message.new(params[:message])
if @message.valid?
NotificationsMailer.new_message(@message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
# To get these actions working, open up config/routes.rb and insert the following two lines
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
# create app/views/contact/new.html.erb
<%= form_for @message, :url => contact_path do |form| %>
<fieldset class="fields">
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email %>
</div>
<div class="field">
<%= form.label :subject %>
<%= form.text_field :subject %>
</div>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
</fieldset>
<fieldset class="actions">
<%= form.submit "Send" %>
</fieldset>
<% end %>
@rietta
Copy link

rietta commented Jan 18, 2012

In the mail function if you set the reply-to header using
:'reply-to' => @message.email
then you can reply to the email even though Gmail will rewrite the address in the From header. I ran into this recently and blogged about it at http://blog.rietta.com/2012/01/rails-gmail-reply-to-on-contact-form.html. Thank you for the Gist.

@stanmx
Copy link

stanmx commented Jul 24, 2013

Randy, i follow your original post http://matharvard.ca/posts/2011/aug/22/contact-form-in-rails-3/ to here.

Im implement the steps in a localhost project. I render the notifications_mailer/new_message.text.erb in the terminal, but my question is: if only work in production or in a hosting project.

I hope you can anwser me. Thank you!

@stanmx
Copy link

stanmx commented Jul 24, 2013

Works, i move smtp_settings.rb content to environments/development.rb

config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'mail.mydomain.cc',
:port => 587,
:domain => 'mydomain.cc',
:user_name => 'me@mydomain.cc',
:password => 'mypassword',
:authentication => :login,
:openssl_verify_mode => OpenSSL::SSL::VERIFY_NONE,
:enable_starttls_auto => false
}

config.action_mailer.default_url_options = {
:host => "localhost:3000"
}

In the contact/new.html.erb file add :method => :post like this:

<%= form_for @message, :url => contact_path, :method => :post do |form| %>

Thank you for you tutorial, i will make a spanish version. Buen dia!

@matthewnolan
Copy link

Problem with the routes

Invalid route name, already in use: 'contact' (ArgumentError)
You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming.

@troystarwalt
Copy link

Thanks for this!

@wood-archer
Copy link

define your routes like this:
get 'contact' => 'contact#new'
post 'contact' => 'contact#create'

@limjinyung
Copy link

Screenshot from 2020-01-14 12-12-36

Sorry, I've like to ask why I am having this error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment