Stac Blog

July 11th, 2014 by Josh

Case Study: NHSx

It's not often that you get a call from the NHS asking you to build a learning platform from scratch, using the latest technologies and delivered using agile management practices, but one February morning we were faced with exactly that.

Alongside good friend Harry Roberts (who's also done a nice write up of the project here) we met Jason, the NHS Leadership Academy’s Programme Lead, and after a short discussion we agreed this was definitely a project we'd like to be involved in.

NHSx

Overview

The aim of the project was to build a learning platform that could be used to distribute educational content to anyone, at any level within the NHS. Whether they're a nurse or an executive, the platform needed to provide a place for them to take part in online programmes and report their progress back to coaches and programme leads.

On top of this, we also needed to make sure that the content packages were easy to author and manipulate. The platform needed to satisfy the users who administered the programme content just as much as the participants, as the quality of the content was just as important. There were already systems out there that supported a variant of what we needed, but they didn't fit the delivery model we had in mind, so we worked with the authors to build something more suitable for the platform. This resulted in a custom package format that meant authors could create learning content, add resources such as videos and images, and bundle it all up into a single upload to publish on the platform.

Process

One of the most refreshing aspects to this project was how it was run and delivered. IT projects in the public sector are mostly publicised for being monolithic beasts resulting in bloated software and off-the-mark deliverables, but I'm glad to say that this project couldn't have been more different. It's a huge credit to Jason and his team that the project was delivered on time and to the specification.

On top of that, it was all done in an agile manner. We used tools like Trello and Slack to keep communication tight, and GitHub to keep conversations around code focused and relevant. During a series of 14 sprints we took the project from MVP to final deliverable. We used a staging server to preview code before production releases to ensure internally we were happy with how things worked, and we used automated deployment processes to push code live.

It was made even more enjoyable by Jason allowing the development team to just "get things done" without too much bike-shedding about how we were doing things, with the knowledge that we had the experience to deliver what was asked of us.

Detail

The main platform project was build in Rails 4, using a small handful of gems to speed up development of some common features. Alongside this, Harry worked on a UI Toolkit written in Sass. We worked on the functional and presentational sides of the application in separate branches (using Git), until we were ready to pair the work up.

A bit more detail about the technology used on this project:

  • To run the app itself we used Foreman and Unicorn. Using Unicorn allowed us to deploy the app with zero downtime using rolling restarts
  • Dragonfly was used a lot, not only for image uploads, but storing assets and content packages, and post-processing assets into cloud storage
  • App Signal meant we were notified of any production errors or performance regressions
  • Rack Cache helped us tune some heavy page requests and dragonfly downloads
  • Ember.js allowed us to create mini applications that we could embed into certain parts of the site which required richer features (such as private user portfolios)
  • jBuilder helped us build a more consistent API for the JavaScript applications by treating our JSON views just like any other Rails view
  • Capybara and Site Prism allowed us to thoroughly test the entire stack, along with the usual unit and controller specs

Alongside the technologies listed above we also created some private gems to support some more bespoke features of the platform such as content delivery (which used our custom package format), application permissions, and feature flags so we could easily enable features for certain participants.

Summary

It was a pleasure to be a part of such an agile team, especially on a project with such a large impact on its user base. We can't wait to see how the project evolves and matures as more learning content gets added, and we look forward to seeing the Leadership Academy continue to improve the jobs and lives of people who have used the platform, delivered by a small team in just a few months.

April 15th, 2014 by Josh

Action Mailer Interceptors

There's a little known feature in ActionMailer called Interceptors. If you've ever wanted to conditionally alter an outgoing email within a Rails application, Interceptors are what you're looking for.

Interceptors allow you to do exactly that, intercept an outgoing email. It's at this point you can choose to alter the to address, add a BCC address, or stop the mail from sending altogether.

Example

Let's look at how Interceptors work. Firstly, define a class which responds to the .delivering_email class method. This will accept a single argument, the mail object:

class RedirectOutgoingMails
  class << self

    def delivering_email(mail)
      mail.to = 'test@example.com'
    end

  end
end

In the above Interceptor, we're overriding the to address to only send to test@example.com regardless of who the mail was meant to go to.

Now the Interceptor needs registering with ActionMailer:

ActionMailer::Base.register_interceptor(RedirectOutgoingMails)

Once registered, this will intercept all mails. This might not be what you want, so let's look at adding it only for certain environments:

if %w( development staging ).include?(Rails.env)
  ActionMailer::Base.register_interceptor(RedirectOutgoingMails)
end

Now we'll only have the mails intercepted in our development or staging environments. This can be particularly useful if you use sample data from production on staging, and don't want to accidentally email real users (although we wouldn't recommend directly using live data on staging).

Other Uses

As we have access to the entire mail object, we can do more than just alter the to address. We can, for example, stop delivery of the mail altogether:

class HaltMailDelivery
  class << self

    def delivering_email(mail)
      mail.perform_deliveries = false
    end

  end
end

Or we could BCC in all admin users to all emails:

class BccAdminsToAllMails
  class << self

    def delivering_email(mail)
      mail.bcc = User.where('admin = ?', true).pluck(:email)
    end

  end
end

Refactoring

One slight improvement we could make to the original example is to source the override email addresses from the ENV constant, so we don't need to make code changes when we want to change the to addresses:

class RedirectOutgoingMails
  class << self

    def delivering_email(mail)
      mail.to = to_addresses
    end

    def to_addresses
      raw = ENV['MAIL_INTERCEPT_ADDRESSES'] || ''
      raw.split(',').map(&:strip)
    end

  end
end

Now all we need to do is change the config value in MAIL_INTERCEPT_ADDRESSES and restart our application and the changes will take effect.

January 27th, 2014 by Josh

2013 Recap & Latest News

Better late than never, we wanted to take a moment to recap last year and provide a brief update of plans moving forward. 2013 was a great year for Stac, and we're incredibly excited about what we've got lined up for this year.

Hey!Stac

June saw the first Hey!Stac event take place just below Stac HQ in The Faversham. Since then, we've seen a great community grow with many loyal, familiar faces.

With 17 talks so far, focusing on a wide range of topics from development to mental health, we're really interested to see where we can take the event over the next year.

Hey!Stac's aim has always been to build and support a community of skilled and passionate people, whether they're developers, designers, writers, project managers or business owners.

This year we're focusing on putting more effort into planning the events and supporting speakers to ensure we can keep things flowing. In light of this, we're happy to announce the next three events will be on the 28th January, 25th February and the 25th March.

We're also looking for formal sponsorships to ensure that we can put on the best events possible; if you're a company looking to get involved, please get in touch.

Client Success

New Year's Eve saw the conclusion of a year long project to launch the next iteration of our Manchester client Fatsoma's ticket sales platform. It was great to see them top a new record in sales over the Christmas period, and we're sure that the success of the platform and the business itself will continue to grow as they expand their team. It's been a pleasure working with a company with such a clear vision on how the future of ticketing should be, and we're proud to have played a part in that.

Leeds, Manchester and London

Alongside Leeds and Manchester we're excited to add London as a third location for Stac. With a thriving startup culture and many interesting technical problems to solve we're really keen to meet businesses who we can support and grow with. Although we're taking our offering down to the capital, we're not abandoning our northern roots, and Leeds will remain firmly planted as our base.

Blog Content

We're also looking forward to putting more effort into publishing content surrounding Rails and Ember.js, as well as other non-technical posts. Keep an eye out for more posts coming soon.

Thanks to all our clients and the community that's supported us through 2013, we hope to see many new faces at our upcoming events, and here's to 2014!

October 31st, 2013 by Josh

Creating A Rails-Style Flash Object With Ember.js

If you've used Rails for a while you'll be familiar with flash messages. Flash objects provide a way to temporarily store information to recall later (usually on the next page render). This can be really useful for performing an action in a controller and then setting a feedback message to show the user during the next action.

We've done a lot of work with Ember.js lately, and we needed this functionality to feedback model saves to the user. There are already a wide variety of solutions out there, including the awesome Growl-esque notifications by Aaron Haurwitz, but for one of our smaller projects we wanted something simpler.

We're already using Foundation for it's excellent grid system, so we wanted to re-purpose the alert component into Ember.js flash object.

You can view the complete demo here, what follows is a break down of each concern. Please note that this demo assumes you have the Foundation CSS and Ember.js loaded on the page.

Model

Firstly, we'll create the flash model, responsible for storing information such as the type of message (alert and success) and the message content itself.

App.FlashModel = Ember.Object.extend({

  type : null,

  message : null,

  isAlert : Ember.computed.equal('type', 'alert'),

  isSuccess : Ember.computed.equal('type', 'success'),

  clear : function(){
    this.update(null, null);
  },

  update : function(type, message){
    this.set('type', type);
    this.set('message', message);
  },

  success : function(message){
    this.update('success', message);
  },

  alert : function(message){
    this.update('alert', message);
  }

});

View

Then we'll create a view, which will be backed by the flash model. This is responsible for binding to model properties and ensuring the view reflects the current model state. It also handles hiding the modal by clearing the flash data from the model on a click event.

App.FlashView = Ember.View.extend({

  templateName : 'flash',

  classNames : [ 'alert-box' ],

  classNameBindings : [ 'success', 'alert' ],

  messageBinding : 'model.message',

  alertBinding : 'model.isAlert',

  successBinding : 'model.isSuccess',

  isEmpty : Ember.computed.empty('message'),

  didInsertElement : function(){
    if(this.get('isEmpty'))
      this.hide();
  },

  onMessageChange : function(){
    this.get('isEmpty') ? this.hide() : this.show();
  }.observes('message'),

  hide : function(){
    this.$().hide();
  },

  show : function(){
    this.$().show();
  },

  click : function(e){
    e.preventDefault();
    this.get('model').clear();
  }

});

Template

As well as the view object itself, we'll create the template, which simply renders the flash message. All foundation classes are taken care of by the view object.


Application

Now we'll write the glue code which uses the flash object (for the purposes of this demo only). We'll create an Ember application object, which acts as the namespace for everything app related. All views and models will be stored on this object.

App = Ember.Application.create();

Alongside the application object, we'll want to add a template, which renders the current route via the outlet and the flash view as part of the main app layout. The flash view binds the model to the global App.flash object (which we'll set later on).


Then we'll define an index view and route. The view defines action triggers which call actions within the route that change the state of the flash object.


App.IndexRoute = Ember.Route.extend({

  actions : {

    setSuccess : function(){
      App.get('flash').success('This is a success message.');
    },

    setAlert : function(){
      App.get('flash').alert('This is an alert message!');
    },

    setCleared : function(){
      App.get('flash').clear();
    }

  }

});

Finally, we'll create an instance of the flash on the application (which is used in the application layout).

App.set('flash', App.FlashModel.create());

Summary

This demo reveals some of the power behind Ember.js. Computed properties and bound objects are concepts that really help keep your code concise and tidy. After using Ember for only 6 months, we can't imagine how we made large JavaScript apps without it.

Hat tip to Luqman Amjad for working with me on the initial component.

July 4th, 2013 by Brent

Hey!Stac #2 and Sister Site

After the success of our first Hey!Stac event last month we're pleased to announce the second, which will take place on the 23rd of July. If you attended the first time round, please join us again. If you didn't feel, free to come along.

In conjunction with the next set of talks we're launching a new sister site hey.wearestac.com. There you'll find information about the next event and where to find us.

As always, we look forward to seeing you and get in touch if you'd like to present in the future.

June 6th, 2013 by Brent

Recap of Hey!Stac #1

Many thanks to everyone that attended our first Hey!Stac event on June the 4th. We hope you enjoyed it as much as we did. A special thanks to Harry Roberts and Andrew Nesbitt for their excellent talks, and to Louise Brogan-Hewitt for the awesome brownies!

Harry Roberts kicked the night off with a talk explaining the benefits of designers adopting developer best practices. Josh and I then followed with a presentation about our first (failed) attempt at creating a software startup and what we learnt from the experience. Finally, Andrew Nesbitt closed with slides and a set of demonstrations where he flew a quadcopter with various controllers via Node.js.

We plan to make the night a regular meet up and will be confirming the date for the next one soon. Feel free to join us whether or not you attended the first time round, and if you'd like to give a talk on something that interests you please get in touch.

You can see the photos from the evening on Flickr.

Harry Roberts
CSS - You've Been Doing It Wrong

Josh Nesbitt & Brent Murphy
Signal Box - Burn After Coding

Andrew Nesbitt
Node.js and Quadcopters - What could go wrong?