An Email Form with Ruby on Rails

The one thing that I’ve been struggling with the most during my Ruby on Rails learning curve is how to create a simple email form for any web applications I may want to create. There was nothing to be found on Google so in my initial attempt I worked through the ActionMailer documentation on the RoR wiki website. I put it all together and, feeling really pleased with myself, clicked the send button. Nothing at all, just lists of errors, so I modified it and still more errors. After posting on Ruby Forum and with the help of a talented member I finally got it working.

This post is for all the people like me who don’t know what to do.

First of all, this tutorial assumes that you already have a basic RoR web application set up with a ‘Contact’ controller and a main view for the index in the controller.

Now the real work starts. Open up a terminal session (or SSH) and navigate to your rails application’s directory (for this tutorial the rail application will be ‘rails_app’).

cd /rails_app

Then create the mailer, ‘Emailer’ is the name of the model that will be produced.

./script/generate mailer Emailer

Now, that’s all the terminal work done. Lets start the setup.

In your chosen editor open the file ‘/rails_app/config/environment.rb’ and place the following inside the ‘Rails::Initializer’ block customizing all the necessaries to your SMTP server’s configuration.

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address => 'localhost',
  :domain => 'website.co.uk',
  :port => 25,
  :authentication => :login,
  :user_name => "smtp_username",
  :password => "smtp_password"
}

config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_charset = "utf-8"

Now open the file ‘/rails_app/app/models/emailer.rb’ and make it look like the below, again customizing the necessaries (but do not touch the variables).

class Emailer < ActionMailer::Base
  def contact_email(email_params)
    # You only need to customize @recipients.
    @recipients = "contact@website.co.uk"
    @from = email_params[:name] + " <" + email_params[:address] + ">"
    @subject = email_params[:subject]
    @sent_on = Time.now
    @body["email_body"] = email_params[:body]
    @body["email_name"] = email_params[:name]
    content_type "text/html"
  end
end

In the controller for your contact page you will need to make the following changes, basically, adding a definition for ‘send_mail’.

def send_mail
  Emailer::deliver_contact_email(params[:email])
end

Go to the ‘/rails_app/views/emailer’ folder and create a file called ‘contact_email.html.erb’. In this file place the following code.

<p>Name:</p>

<p><%= @email_name %></p>

<p>Message:</p>

<p><%= @email_body %></p>

The final step is to create a form on the ‘Contact’ page that will allow the website to user to input and submit the email. An example for is illustrated below.

<% form_for :email, :url => { :controller => 'contact', :action => 'send_mail' } do |f| %>
  <%= f.label :name %><br />
  <%= f.text_field :name, :size => 60 %><br />
  <%= f.label :address %><br />
  <%= f.text_field :address, :size => 60 %><br />
  <%= f.label :subject %><br />
  <%= f.text_field :subject, :size => 60 %><br />
  <%= f.label :body %><br />
  <%= f.text_area :body, :rols => 10, :cols => 60 %><br />
  <%= submit_tag "Send Email "%>
<% end %>

That’s about it really, you may want to add your own error handling as this example only covers the basics. If you go to the contact page you can see a working example of the above tutorial in action. There are probably easier ways of doing this than the method I have described, but I like my method and hopefully it will work for you.

Update: The code in this post was updated for Rails 2.0.x on 17th March 2008.

Update: Modified the settings code to be ‘smtp_settings’ rather than ‘server_settings’, thanks goes to Lyle for discovering the problem (below).

Update: Modified the code to work for Rails 2.3.x onwards (but not Rails 3).

An Email Form with Ruby on Rails