Sending SMTP E-mails With Ruby on Rails

July 31, 2007 – 4:21 pm

In my development environment, it was almost trivial to send the E-mails via sendmail; however, it was frustrating to get SMTP to work with MediaTemple.net. After several hours of trial and error and searching various resources I was able to get everything working. This article will document the entire process, from setting up your Ruby on Rails (RoR) container to sending the E-mail within your RoR applications.

Setting up the RoR Container

1. Login to your MediaTemple.net account.

2. Click on the domain name that will contain your RoR application.

3. Click on Manage this Server.

4. Click (gs) gridContainer.

5. Click the button next to the Rails Container icon and follow the instructions to install.

Initializing the Application

Carefully follow the instructions here.

Configuring ActionMailer

Make sure the outgoing SMTP server is working first. The following files and their contents should be in your config/enviornments directory:

boot.rb

unless defined?(RAILS_ROOT)
  root_path = File.join(File.dirname(__FILE__), '..')
  unless RUBY_PLATFORM =~ /mswin32/
    require 'pathname'
    root_path = Pathname.new(root_path).cleanpath(true).to_s
  end
  RAILS_ROOT = root_path
end
unless defined?(Rails::Initializer)
  if File.directory?("#{RAILS_ROOT}/vendor/rails")
    require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
  else
    require 'rubygems'
    environment_without_comments = IO.readlines(File.dirname(__FILE__)
            #This should be appended to the line above, I separated for formatting
            + '/environment.rb').reject { |l| l =~ /^#/ }.join
    environment_without_comments =~ /[^#]RAILS_GEM_VERSION = '([\d.]+)'/
    rails_gem_version = $1
    if version = defined?(RAILS_GEM_VERSION) ? RAILS_GEM_VERSION : rails_gem_version
      rails_gem = Gem.cache.search('rails', "=#{version}").first
      if rails_gem
        require_gem "rails", "=#{version}"
        require rails_gem.full_gem_path + '/lib/initializer'
      else
        STDERR.puts %(Cannot find gem for Rails =#{version}:
    Install the missing gem with 'gem install -v=#{version} rails', or
    change environment.rb to define RAILS_GEM_VERSION with your desired version.
  )
        exit 1
      end
    else
      require_gem "rails"
      require 'initializer'
    end
  end
  Rails::Initializer.run(:set_load_path)
end

mail.yml

---
method: smtp
smtp_options:
  :port: "25"
  :domain: [yourdomain.com]
  :user_name: [your username]
  :password: [your password]
  :address: [mail.yourdomain.com]
  :authentication: :login

environment.rb

require 'yaml'
RAILS_GEM_VERSION = '1.2.3'
require File.join(File.dirname(__FILE__), 'boot')
mailconfig = YAML::load_file(File.join(File.dirname(__FILE__), 'mail.yml'))
Rails::Initializer.run do |config|
  config.action_mailer.delivery_method = mailconfig['method'].to_sym
  config.action_mailer.raise_delivery_errors = true
end
ActionMailer::Base.server_settings = mailconfig['smtp_options']
puts YAML::dump(mailconfig['smtp_options'])

Using ActionMailer

1. Create the E-mailer class

In the folder app/models create the following file:

notifier.rb

class Notifier < ActionMailer::Base
  def signup_report( email )
    recipients "[your email or the emails of the recipients]"
    from "[email address of the SMTP account]"
    subject "[string]"
    #The parameters set here will be available in the view template
    body :user_email => email
  end
end

The template for the sent email will be located at app/views/notfier/signup_report.rhtml:

signup_report.rhtml

<%= @user_email %>

In this case I just want the body to contain the submitted E-mail address.

Following is the form used to capture the E-mail. Note that the old syntax for form_remote_tag is used. The new syntax is not working with MediaTemple.net, it returns a blank form. Place this code in your view.

<%= form_remote_tag(:url => { :action => :form_tag_splash },
     :update => :results,
     :complete => visual_effect(:highlight, 'results')) %>
<%= text_field_tag('email', '', {:size, 30, :maxlengh, 50})%>
<%= submit_tag 'Request Beta Invitation' %>
<%= end_form_tag %>

Here is the controller code (corresponding with the above form in its view) used to send the E-mail:

def form_tag_splash
  @result = params[:email]
  Notifier.deliver_signup_report(@result)
  render :partial => 'form'
end

The partial _form.php is defined as follows and should be in the same directory as the view:

Thank you for your interest. We will send all updates to <%= @result %>. Please add info@notifir.com to your safe list.

Thats it. Now you have a re-usable class to send E-mails from your Ruby on Rails application.

Elmer Thomas Jr. is Co-founder of ATL Innovations, Inc., an award winning web and software development company dedicated to bridging the digital divide, ThemBid.com, a service offering free advertising for businesses that makes finding services and products easy for consumers, and Notifir.com, a service making social news networking fun, easy and productive. You can find out more about Mr. Thomas at ElmerThomas.com.

  1. 2 Responses to “Sending SMTP E-mails With Ruby on Rails”

  2. Question!

    What is the purpose or advantage of using RoR for email??

    please reply here or to my yahoo email.

    By Hammy on Aug 1, 2007

  3. I got it working in MediaTemple.net. Now, I want to write cronjob for sending mails. Can you explain me the steps?. Thanks.

    By arthur on Aug 13, 2007

Post a Comment