This is my third post on sending emails in Ruby; you can find the first here and second here. Today we are going to use Pony to send out our email. Pony, claims to be the express way to send emails in Ruby, it was created to give Rubyist the same feel as PHP’s mail function that sends an email in a single command.

Pony uses /usr/sbin/sendmail to send mail if it is available; otherwise it will fall-back to SMTP. You can specify from the get go that Pony uses one or the other. Just as ActionMailer does Pony uses the Mail gem to do the heavy lifting and thus your emails are sent through a tried and tested library used by the majority of the Ruby world.

Since Pony uses Mail internally, you will see a lot of similarities between it, ActionMailer and Mail. Pony is exclusively used to send an email if you would like to process incoming emails you are better off using ActionMailer or better yet plain old Mail.

So getting down to business, we will want to create a new Ruby file for our Pony mailer class. I am going to go ahead and call it using-pony-mail.rb. The first thing you need to do is install the Pony gem using

install gem pony

Next you need to add two requires to your using-pony-mail.rb file, a require to ERB and a require to Pony. Your file should look like this:

require 'erb'
require 'pony'

We will be using ERB to process our email template which means we can use variables in our email template that will be replaced at runtime.

The next step is to define our Mailer class; the Mailer class will receive an options Hash in the initialize method that will be passed off to Pony. Inside our initialize method, we will set the Pony.options.

The Mailer class will need a method that will be called to send our email as with our previous examples we will call this method awesome_email which will accept a Hash called details that will hold everything that is necessary for our email.

In the awesome_email method, we set the context that will be passed off to ERB. The binding class captures the execution context; this is crucial as without the context your variables will not be visible to ERB when generating the email body for your message.

We are now ready to set our options Hash; this Hash is passed into the Mailer constructor and sets certain properties within Pony. Unlike before we, have two new keys in our Hash. The first is the :via_options symbol which contains the SMTP details and then another new symbol :via which states which mechanism to use in sending our emails, since we are using Gmail we are passing in SMTP.

Great we can now create the Mailer object that will be used to send out the email passing in the options Hash that Pony will need. We can also create our details Hash with all the necessary information to set the from and to addresses, the subject line of the email and the path to the email template that ERB will use when sending out an email. Lastly, we can call the awesome_email method on the Mailer object that we created and pass in the details Hash. Here is the full code listing:

Thus, far I believe this has been the least amount of code written between the ActionMailer and Mailer implementations. Pony has quite a nice API, which is straightforward. Pony is pretty awesome if all you need to do is send an email; it uses Mail internally which is used by ActionMailer and well tested and is actively being developed. If all you are going to do is send an email then Pony should be your first choice, if you need to process incoming emails I would say use Mail and if you are building a Rails application just stick to ActionMailer.

I am starting to see a trend here; both ActionMailer and Pony are built on top of Mail it looks to me that Mail is the defacto API used to send emails in modern Ruby libraries.

Discussion, links, and tweets

My name is Deon Heyns and I am a developer learning things and documenting them in realtime. Python, Ruby, Scala, .NET, and Groovy are all languages I have written code in. I appeared in the New York Post once. I host my code up at GitHub and Bitbucket so have a look at my code, fork it and send those pull requests.