Previewing emails in Rails applications with the mail_view gem

Mailer specs are a great to verify that the emails sent from your Rails applications have the required data, links, and important content. But often a developer, or more likely the product owner, may want to see the emails to make sure they are properly formatted, read well, and are free of spelling errors.

Getting your application to send an email from a development or staging environment can be an onerous task depending on how much user workflow and data setup is required for a given email. This is where the mail_view gem can really help you out.

The mail_view gem lets us easily preview emails right from within your Rails application running in the development environment

Using mail_view in Rails 4.1+

Configuring mail_view

mail_view is built into Rails 4.1+, so there is no additional setup or configuration to start using it.

You can read more about support for mail_view in Rails 4.1 in the following links

Edge Guides Release Notes

ActionMailer API Docs

Setting up emails to preview

By default, Rails 4.1 expects the mail preview classes to be located in the test/mailers/previews directory. If you use the mail generator, a preview file will be created for you automatically. You create a class that inherits from ActionMailer::Preview for each email to be previewed.

class WelcomeMailerPreview < ActionMailer::Preview

  def welcome_investor
    user = User.last
    WelcomeMailer.welcome_investor(user)
  end

end

Previewing the emails

Browsing to http://localhost:3000/rails/mailers/welcome_mailer/welcome_investor will show you a preview of the email. But before you do that you will probably need to set up some data for the preview

Using mail_view in Rails prior to 4.1

Configuring mail_view

For Rails versions prior to 4.1, there is just a little work to do to get set up.

First you will need to add the gem to your Gemfile.

gem "mail_view", "~> 2.0.4"

Then you mount the mail_view engine into your application via the routes.rb file.

  if Rails.env.development?
    mount MailPreview => 'mail_view'
  end

I wanted to make the mail_view available on my staging server, so I used an environment variable to enable it.

  if Rails.env.development? || ENV["PREVIEW_EMAIL"] == "true"
    mount MailPreview => 'mail_view'
  end

With the engine mounted at mail_view, browsing to http://localhost:3000/mail_view will present us with a list of emails to preview. But before we do that, we need to set up the emails to preview.

Setting up emails to preview

You set up the emails to preview by creating a class that inherits from MailView

class MailPreview < MailView

  def welcome
    user = User.last
    WelcomeMailer.welcome_investor(user)
  end

  def payment_confirmation
    payment = Payment.last
    PaymentConfirmationMailer.confirmation_email(payment)
  end

  def contact_us
    ContactMailer.contact_email("Joe Smith", "617-555-1212", "jsmith@example.com", "I have a question...")
  end

Listing the emails

Now that we have some emails to preview, we can browse to http://localhost:3000/mail_view will present us with a list of email preview links as defined in the MailPreview class.
Mail Preview List

Providing data for the emails

Typically our emails are working with data from our database. The mail_view documentation describes some of the ways you can provide data to the mailer, using either actual data from the database, using a factory pattern, or providing a stub.

In the examples above, I am using data from the database. Each approach has its advantages and disadvantages, and it really depends on how you data is structured as to which approach you use. You can also mix and match the different approaches as you see fit.

Viewing an email

mail_view displays a preview of the email with the header information shown in the page header and the body in an iframe, as shown below.
Mail Preview As HTML

If you have provided a text and html template for the email, a drop-down is displayed in the page header to allow you to preview the different formats. Here we are displaying the text version of the email
Mail Preview As Text

Since the body of the email is displayed in an iframe, clicking on a link in the email will open the link inside the iframe.
Mail Preview Open Link

Summary

The mail_view gem is a great tool to allow you to visually inspect the emails sent by your Rails application.

Responsive Design Comparison: Neat vs Foundation

In the interest of improving my design skills, I wanted to brush up on a couple of different grid-based systems that provide responsive design capabilities.  There are several to choose from, but I settled on trying out thoughtbot’s neat library and Zurb’s Foundation framework.  Along the way, I also got a chance to play around with thoughtbot’s Bourbon library.

Just The Grid, Thanks

Now first off, comparing neat to Foundation is like comparing apples to fruit salad.  neat is strictly a grid system, it is not a full-blown framework, like Foundation.  There is a time and a place for either approach, but since I wanted to focus primarily on how the two grid systems work I think it is mostly a fair comparison.

I developed two bare-bones apps that just let me play around with the grid system and some basic styling.  All I really wanted to do with the apps was to have a few static pages, see how the grid system layout worked, and how it responded to different screen sizes (desktop, tablet, phone).  The apps can be found here.

These apps are a simulation for a wine store application.  Again, wasn’t going for a full functioning app.  Just wanted the following features in the demo apps

  • Page header with some simple navigation links
  • Home page with a grid-based sections for “Staff picks” and “Calendar of events”
  • Responsive design to change the layout for desktop/laptop, tablet, and phone contexts

tl;dr

Either neat or Foundation is a solid choice for a grid system.  Both default to 12-column grids, and can configured to support other layouts.  Both are really easy to integrate into a Rails application.  Both also have good documentation, though I might give Foundation a slight nod there.

As far as just the grid system, my preference would be for Foundation.  For me, the syntax of defining the grid system seemed a little more straightforward.  I also liked that when nesting, the child elements don’t need to know about the number of columns in the parent.

Going with a full framework also brings some extra functionality.  I was able to play around with the block grid, the top-bar navigation, and the easy to set up “hamburger” menu icon.  I think it has really solid documentation as well.

Now let’s get to the details…

neat

neat defaults to a 12-column grid, which I like a lot since your sections can easily switch between multiples of 3 or 4 without changing the overall number of grids.  You have the ability to configure the number of columns you want the grid to have, but I had no reason to want to do that with what I was doing.

A grid region is defines using the outer-container mix-in.  According to the neat docs, you can have multiple outer-containers on a page, however they can not be nested.  Given the simplicity of my app, I just threw it on the body element.

body {
  background-color: $background;
  color: $text;
  font-family: 'lato';
  @include outer-container;
}

The span-columns mix-in is used to specify how many columns an element should span.  If the element is nested, you must also specify the number of columns its parent element contains, for example, @include span-columns(4 of 8) specifies that the element takes up 4 columns of an 8 column parent.  I personally found having to specify the parent information to be a bit of a nuisance, and one where neat and Foundation differed.  It wasn’t a show-stopper, but I didn’t like having to concern myself with it.

Responsiveness is attained using the media mix-in.  Inside of the block for the media mix-in, you can define the features for that context.  This allows you to redefine columns, font sizes, whatever for that particular context, e.g. tablet or mobile.  This gives you a lot of control, but to me felt a little heavy. Here you can see where I define that an element normally spans 4 of 8 columns, but for the tablet and mobile contexts spans 4 of 4 columns.

.staff-pick {
  @extend .tile;
  @include span-columns(4 of 8);
  @include omega(2n);
  @include media($tablet) {
    @include span-columns(4 of 4);
    @include omega();
  }
  @include media($mobile) {
    @include span-columns(4 of 4);
    @include omega();
  }
...
}

You can also change the width for when the context switches as well as the number of columns in the grid for the context using the new-breakpoint mix-in.  For my application, I went with an 8 column tablet breakpoint and a 4 column mobile breakpoint.

$tablet: new-breakpoint(max-width 900px 8);
$mobile: new-breakpoint(max-width 600px 4);

I think one of the strengths of neat may be that you have very fine-grained control or the grid and underlying elements through the multiple mix-ins it provides, but that will also take a little more work (or familiarity on neat) on your part.  I also found it required reading both the gem docs on github and the neat page docs to fully understand how to set it up and get running.

Foundation

As I said earlier, Foundation is a full blown framework, along the same lines as Twitter Bootstrap.  You get the grid system, but also navigation elements, buttons, forms, controls of all different kinds, alerts, drop-downs, and on and on.  But for the purposes of this comparison, I wanted to concentrate primarily on the grid system.

Like neat, Foundation uses a 12-column grid, and like I said earlier, a 12-column grid has a lot of advantages.  You can also customize the number of columns in the grid system, but the default was fine for what I was doing.

Foundation uses a different format for specifying the grid layout.  Rather than try and spell it out in all it’s detail, take a look at the grid documentation.  Overall, I found the ability to specify the columns all on one line more readable than the way neat does it.

To define an element that spans 4 columns for large screens and 2 for mobile, you would do something like this

<div class="row"> 
  <div class="small-2 large-4 columns">...</div>
  ...
</div>

Whereas with neat, you would do it this way

  .some-style {
    @include span-columns(4);
    @include media($mobile) {
      @include span-columns(2);
    }
  }

Foundation also has some nice features that make layout a lot easier, IMO.  My toy app had a section for “Staff Picks” that displayed a bunch of wines in a grid layout.  With Foundation, I could use the Block Grid feature to easily lay out the grid based on the screen size.

<div class="row">
  <ul class="small-block-grid-1 medium-block-grid-1 large-block-grid-2">
    <% @reviews.each do |review| %>
       .......
    <% end %>
  </ul>
</div>

Now in 1 line, I can easily see that the block-grid will have

  • 1 review per row for a small screen
  • 1 review per row for medium screen
  • 2 reviews per row for large screen

Foundation also provides some easy mechanisms to implement a “hamburger menu” (the three vertical bars) for the navigation links when going to a small screen, using the class=”toggle-topbar menu-icon” line.

<nav class="top-bar" data-topbar>
  <ul class="title-area">
    <li class="name">
      <h1><%= link_to "Denomy's Wine Emporium", root_path %></a></h1>
    </li>
    <li class="toggle-topbar menu-icon"><a href="#"></a></li>
  </ul>
  <section class="top-bar-section">
    <ul class="right">
      <li><%= link_to 'Home', root_path %></li>
      <li><%= link_to 'About', about_path %></li>
      <li><%= link_to 'Help', help_path %></li>
    </ul>
  </section>
</nav>

Foundation also provides a lot of tools for handling nesting, offsets, incomplete rows, and other potential gotchas that really look great for helping to manage the grid.

Given that you get a lot of other features with it, like forms, alerts, drop-downs, etc, I am really starting to look forward to using Foundation more in the future.

It wasn’t all perfect, there were some annoying things.  For instance, I was unable to use a linear gradient in the header bar, but for the most part it was pretty easy to work with.

Adding In a Splash of Bourbon

I am happy to say that it was easy to use both neat and Foundation in a Rails app with Bourbon.  Bourbon has some a really rich set of SASS mixins that can be used to customize the look of your app.

Programmatically Clearing the Facebook Share Image Cache

When you share a URL on Facebook, it scrapes the page for the URL for the Open Graph data to determine what image/video to display.  Facebook caches the image for that URL, so if you change the image and then share the same URL at a later time, the old image will still get displayed, which is probably not what you want to do.

Facebook provides the Open Graph Debug Tool that can be used to manually clear the cached value for the URL, but that may not be a workable if your website allows images to be changed dynamically.  Ideally, you would want a way to programmatically clear the cache after the associated image is changed.

Fortunately, there is a way to clear the cache using the OpenGraph API by forcing a scrape of the URL. The key is to set the ‘scrape’ parameter to true in the API call. The following Ruby code assumes that the Facebook application id and secret are stored in environment variables.

facebook_open_graph.rb

module FacebookOpenGraph
  def self.clear_cache(url)
    params = {
      :client_id => ENV['FACEBOOK_APP_ID'],
      :client_secret => ENV['FACEBOOK_SECRET'],
      :grant_type => "client_credentials"
    }
    uri = URI("https://graph.facebook.com/oauth/access_token?#{params.to_query}")
    response = Net::HTTP.get(uri)
    access_token = Rack::Utils.parse_nested_query(response)["access_token"]
    unless access_token.nil?
      uri = URI('https://graph.facebook.com')
      res = Net::HTTP.post_form(uri, 'id' => "#{url}", 'scrape' => 'true',
          'access_token' => "#{access_token}", 'max' => '500')
    end
  end
end

Then to clear the cache you merely need to call the clear_cache method, passing in the URL being shared.

FacebookOpenGraph.clear_cache("http://myurl.com/some_cool_page")

Aikido, Controller Tests, and LinkedIn at Launch Academy

I had a nice visit the other day speaking at Launch Academy.  It’s no secret that I am a big fan of the program.  As a community, we need to do more to produce good entry-level developers and also to help them develop their careers.

My talk was geared towards preparing them for what happens when they leave Launch Academy and some of the things they can do to continue learning and growing as software developers.  The three topics: Aikido, Controller Tests, and LinkedIn don’t seem to have anything to do with one another, but let’s look a little closer.

Aikido

I don’t know the first thing about aikido, but I do know of a talk that Alistair Cockburn gave where he talks about aikido and the three stage of learning: Shu, Ha, and Ri.  These stages of learning are common to almost any endeavor, including software engineering.  Right now, the students at Launch Academy are in the shu phase, learning a single technique from their masters.

When they go out into the world, they will be exposed to new techniques and new masters, and it is their responsibility to be open to these new techniques, try them out, and incorporate them into their own practices.  This is the ha phase.

With some hard work, practice, and luck they may reach the ri phase, where they are inventing their own techniques, but that wasn’t part of my talk.

I highly recommend the talk by Alistair Cockburn, it covers so many great ideas about developing your craft.  He is an amazing guy and his talks are always engaging.

Controller Tests

I have been thinking a lot lately about controller tests in Rails.  What value do they serve, are they still worth writing?  This is probably the subject of another blog post or series of posts, but in the talk I wanted to tie it in with the concept of shu-ha-ri and being open to new ideas.

When I first started learning Rails, one of my primary resources was Michael Hartl’s amazing tutorial.  So many of us owe him so much for showing us the way into an awesome framework.  At the time I was learning, I recall the tutorial having a fair number of controller tests, and those tests became part of my shu learning phase of Rails.

As I started to develop more Rails apps, and getting exposed to more practices and techniques, I was forced to rethink the role of controller tests.  I found some of the ways I was using them had little intrinsic value.  In some cases, they were essentially testing the framework (e.g. index action rendering index template) or were a mix of controller and view tests that were brittle and not as comprehensive as a Capybara feature spec.

Taking a ri approach, I have adapted my practices to do more outside-in tests.  These have the advantage of reinforcing the customer experience and keep me from diving too deep too soon.  They allow me to explore the data relations and behaviors before getting in to specifics about the low-level details.

It is interesting to note that in researching the talk, I could not find many (if any) controller tests in the current edition of Hartl tutorial.

LinkedIn

The third phase of the talk took a bit of a left turn, but I think is an important lesson for someone trying to break into the field.

I am a big believer in REAL networking, i.e. talking to people, building relationships, asking questions, and following up.  I have made some awesome friends, mentors, and mentees in the Rails community.  It took me too long to learn how to effectively meet people and build relationships.  Fear and imposter syndrome are tough things to overcome.

I see a lot of people not networking effectively and it makes me sad.  We had a really good discussion about getting out and talking to people, sending follow up/thank you emails, and personalizing your LinkedIn invites so the person on the other end remembers you and is inclined to accept your invite.  A big key is following up, if you make a contact at a meetup, say hello at the next meetup, ask a question about something they told you about themselves, be genuine.

As always, it was great to meet another Launch Academy cohort.  I hung around for quite a while and the Launchers had awesome questions.  Looking forward to seeing them out in the community soon.

Facebook URL Linter, Critical Errors, and Rackspace

When you share a URL on Facebook, Facebook will scrape the page to find the Open Graph data embedded in the page.

Facebook also provides a tool called the Open Graph Object Debugger to help you debug errors found in the page.  This can be rally useful if, for instance, your tags are not well-formed, or there are problems with the images or videos that are on the page being shared.

Sometimes, unfortunately, you get a dreaded “Critical Errors That Must Be Fixed – Error Linting URL” as shown below.

UrlLinterCriticalError

Unfortunately, this doesn’t tell you a lot about the cause of the error.  I was trying to have an image display using the og:image tag.  I had been able to successful share pages that had images that were in my Rails  asset directory, but this particular page used an image that was hosted on Rackspace Cloud Files.

To try and diagnose whether there was a problem with the image (e.g. corrupt file, invalid size for Facebook, etc) I downloaded the image and stored it in my Rails assets.  Everything worked fine.  No errors from the Facebook URL Linter.  The problem must have something to do with the storage on Rackspace.  But browsing to the image on Rackspace worked fine as well.  The image displayed fine in the browser and was publicly accessible.

Why wasn’t the Facebook URL Linter able to parse it?
Well when you store files with Rackspace Cloud Files, you get a pretty hideous URL, like

http://12345678901234567890-12345678901234567890123456789012.r12.cf3.rackcdn.com

A URL is a URL right?  Well yes and no.  I think the Facebook URL Linter finds this to be a pretty suspect URL and considers it spammy.  So I needed to make the URL a little more “friendly” to a spam filter.

The answer was to use a CNAME to map a more readable URL to the Rackspace URL.

My client’s site is hosted on GoDaddy, so that meant going into their DNS settings and adding a CNAME record to point to the Rackspace URL.  I picked something meaningful like “images”.  So now my og:image tag could change from

<meta property="og:image" content="http://12345678901234567890-12345678901234567890123456789012.r12.cf3.rackcdn.com/some_image.png">

to

<meta property="og:image" content="http://images.mydomain.com/some_image.png">

In hindsight, the CNAME is a good idea on its own. Sure it might be an extra hop to get the image, but having a more logical URL makes a lot of sense, and it also makes in easier to change where your images are stored.

Reinventing Yourself at Boston Ruby

I gave a talk at the November 2013 Boston Ruby Meeting about my experience moving back to a development role after working the last few years in more managerial roles in the medical device/laboratory automation space.

My hope was that this talk would help people starting out in the Rails world, or perhaps people who are transitioning to Rails from the Java or .NET worlds as I was.

Along the way, I also talk about ways to establish yourself in a new development community and how to build up your network beyond just adding people to your LinkedIn network

Rebirth of the PWA – Mentors Wanted

I had a shitty job once.  I know, hard to believe, it must be such a unique and rare experience.  Don’t worry recent employers, it wasn’t you.  It really was a long, long time ago in a galaxy far, far away (the ’90s).

I won’t bore you with the particulars, but something interesting grew out of it.  One day while walking with some co-workers at lunch, we came across a previous co-worker who had left the company for greener pastures. We all unloaded our woes on this poor unsuspecting chap, how bad things were, how much we hated it. It was pretty pathetic.

After we parted ways, my current co-workers and I realized how we had let ourselves slip. Sure our jobs sucked and our boss was a lunatic (he really was) but that was not an excuse for letting things get so far. We made a pact that day that we would find ways to make things better, if only for ourselves.  And so we formed the PWA, the Positive Workers Association.  We would encourage one another to build our skills and make our work lives generally better. We set goals and held each other accountable. These goals were all things that helped us at our current job, so it wasn’t like we were learning Italian to pass the time.

My company uses the 37 Signals product Know Your Company.  Today’s question was “Is anything holding you back from doing the best work you can do right now?”.  My answer covered a lot of ground, but one area that I touched on was that the things I was doing to learn and grow lacked planning and a road map. I invest a lot of time into being better at what I do, and the last few years have been about getting better as a web developer, specifically in Ruby.

But where do I go now? And who is going to call bullshit on me when need be.

So maybe it is time for a rebirth of the PWA, specifically I think it is time to build some new mentoring and peer relationships. Good relationships go both ways, so hopefully you are also interested in finding ways to improve yourself and would benefit from a sounding board or a bullshit caller.  If you are interested, I’d love to connect with you, especially if you are in the Boston area.  Ping me on the twitters or contact me mdenomy at gmail dot com.