Tuesday, June 12, 2007
« Parallels is trying to make me a Ruby on... | Main | Create DDD style specifications in Ruby ... »
I must say I'm growing more fond of Rails the more I use it. It seems like it was actually designed by someone writing real applications for a living, and designed to make the common things that we have to do in most applications straightforward and easy.  Tonight I needed to add some logic to send out emails so I read through the ActionMailer chapter in Agile Web Development with Rails.  For those interested, sending out emails in Rails requires that a mailer class be created that inherits from ActionMailer.  The easiest way to do this is to run the mailer generator like so:

script/generate mailer OrderEmail confirm_order

The generator creates a mailer object in the models folder of your Rails application that looks like so:

class OrderEmailer < ActionMailer::Base
  def confirm_order(sent_at = Time.now)
    @subject    = 'OrderEmailer#confirm_order'
    @body       = {}
    @recipients = ''
    @from       = ''
    @sent_on    = sent_at
    @headers    = {}
  end
end

Which we may modify to have the necessary settings, and accept the necessary order parameter like so:

class OrderEmailer < ActionMailer::Base
  def confirm_order(order)
    @subject    = 'Thank you for your Order'
    @body       = {:order => order}
    @recipients = order.customer.email
    @from       = 'steve@sellscoolstuff.com'
    @sent_on    = Time.now
    @headers    = {}
  end
end

The generator also creates a rhtml template for the email in the views/order_mailer folder that can be used to construct the email message.  To send the email is simply a matter of calling the deliver_confirm_order method on OrderMailer.  Take notice that we call deliver_confirm_order and not just confirm_order.  Rails supports either sending emails out by using the deliver_ prefix, or allows the emails to be created by prefixing the mailer method with create_. What's really nice is that the Mailer uses a rhtml template within the views directory for the mailer (views/order_mailer in the example above) to generate the email.  This allows you to create emails using the same mechanisms used to create dynamic pages within Rails.  Plain text emails can be created, or the mailer methods and views can be updated to pass along parameters, which we do above with the order parameter.  The only difference between a mailer template and a template for a controller is that the mailer view is being used to create a text email rather than an HTML page that will be rendered to the browser.

With my mailer in place I had everything I needed to send out the necessary emails.  There was only one problem, on my MacBook Pro the emails I was generating weren't sending.  Luckily I was able to find this page on how to get OS X setup to send emails via SMTP.  After following these steps I updated my /config/environments/development.rb file to have the following settings for ActionMailer and all was good!

config.action_mailer.server_settings = {
  :address => "127.0.0.1",
  :port => 25
}

 |