How to build a portfolio

I seem to answer this question a lot, so I’m just going to write it all down. I’ve been trying to find junior engineers for my company and one of the things I like to see is a small portfolio on GitHub. This begs the question: how do a I make a portfolio? I’m not expecting much, just a few quick projects so I can see your style. Hell, it doesn’t even have to be Ruby. If you want to do something in AppleScript to automate your computer, go for it!

Your first Ruby script

Your first Ruby project, whether you’re an advanced programmer or a beginner shouldn’t necessarily be in Rails.  Just do something simple.  A good example of this is playing around with RSS stuff.  Ruby has RSS parsing baked right in to make this really straightforward.  You could do something that takes in your favorite news feed and outputs all of the titles or greps out all of the links.  The possibilities are endless.

You could also do something like parsing out a document to find the most common words.

While these two examples have no practical value, they will serve as a good exercise so you can try out Ruby without worrying about Gems or outside code.


If you’ve ever learned a new language or framework, you’ve probably started with a tutorial.  One of the best Rails tutorials has to be the one by Mike Hartl.  It takes you step-by-step through building a Rails application from the ground up and gives you a good basis for branching out from there.  Don’t be shy about putting this tutorial code in your portfolio.  We’ve all had to start somewhere and some of the best out there are those willing to show a little humility and talk about where they started.


Assuming you’re programming on Unix, you likely have a number of configuration files in your home folder.  Put these in GitHub.  I’ve tried doing this a couple different ways and the easiest way I found was to fork someone else’s dotfiles repo.  I personally took this one:

Putting your dotfiles up for everyone to see is a really good way to share simple hacks that you’ve done to make your life easier.  I personally love editing my dotfiles and adding in new shortcuts.

Non-code stuff

I was recently chatting with a prospective applicant and he mentioned that he’s been busy storyboarding out an app he wants to do for a game so he doesn’t have any code yet.  I was kind of amazed that he hadn’t yet put this up on GitHub.  Git makes for a great word editor since you can see your changes and allow for quick collaboration.  This may not be part of a formal portfolio, but it really helps to see how someone thinks through a problem.

Ensuring a return

This one tripped me up for a few minutes today so I thought I’d write something up on it.

Given this code, what do you think it would return:

def foo
  "Hello, world."
  "Goodbye, cruel world."

puts foo

Would it be greeting me or say goodbye? It would go with “Hello”. This is because the ensure block doesn’t normally return anything. It is just used after the method returns to wrap up anything that definitely needs to happen.

How would I force it to return something in ensure? You would need to use ‘return’ explicitly like so:

def foo
  "Hello, world."
  return "Goodbye, cruel world."

Now the method will say goodbye like you expect.

DRY Scopes

One of the things you hear over and over again in the Ruby community is DRY,DRY,DRY (don’t-repeat-yourself, for the uninitiated). A couple months ago I noticed that I was making the same changes over and over again in a weird part of the codebase. It happened to be in our scopes. We had a smattering of different scopes dealing with dates and we had several different variations on the simple :between scope. We also had different selections of the dates scopes in different models. Some had the :after scope and some didn’t, etc.

So what’s a good programmer to do? DRY it up!

I first moved all of the scopes into a module and just included that, and lo-and-behold the specs still passed. Problem was though that I couldn’t do this for all of the models since some relied on a column other than created_at. So instead of just creating a separate module, I just made the current one a little more dynamic.

Here are the first two methods that start the magic:

def include_date_scopes
  include_date_scopes_for :created_at

def include_date_scopes_for(column, prepend_name = false)
  return unless self.table_exists?
  if self.columns_hash[column.to_s].type == :datetime
    define_timestamp_scopes_for column, prepend_name
  elsif self.columns_hash[column.to_s].type == :date
    define_date_scopes_for column, prepend_name

The first method is just there to make it easy to include the scopes for a default created_at column. The second one looks at the table to make sure it exists (it gets tripped up initially if the database isn’t loaded). Then it looks to see if the column is either date or datetime/timestamp type to define the scopes appropriately.

def define_timestamp_scopes_for(column_name, prepend_name = false)
  prefix = prepend_name ? "#{column_name}_" : ""

  define_singleton_method :"#{prefix}before" do |time| 
    where{__send__(column_name).lt (time.is_a?(Date) ? time.to_time : time)}

The next method actually defines the scopes. In this case they are more method than scope, but Rails will still treat them the same. This is just one of them, but you can use this as a template. And for the curious, that is not normal scope style. I am using the Squeel gem to make it much easier to read.

Now all I need to do is delete the scopes from a model and add this:


In my code I have it defining 16 different timestamp scopes and 12 different date scopes. You can really get creative with it too. If you have other common queries you run in different models, try and group them together.

Negative Security Testing

Part of my day job is to help with software security at my company. Part of this involves reviewing our controllers to make sure that people who shouldn’t be able to access them can’t get in. I’ve created both Cucumber specs and RSpec examples to do this. So far I prefer the RSpec method since it allows me to do a little more introspection.

A little bit of a background on our setup. Like most Rails shops, we use CanCan for our authorization and Devise for the authentication. With CanCan we define roles for the users such that the roles are granted access to certain areas of the system.

When I first wrote up the blacklist test in Cucumber, I had to manually specify which roles weren’t allowed and which actions to test in each controller. Obviously, this would only do real testing up until a new role or action was added. When I switched to RSpec I was able to just give a whitelist of what roles are allowed and then get the available actions through introspection. See my code below:

class SecurityHelper
  def self.action_names(controller, opts = {})
    actions = controller.class.public_instance_methods(false).reject{|a| a.to_s.starts_with? '_'}
    actions - Array(opts[:except])
  def self.create_insecure_user(opts = {})
    roles = User.available_roles - Array(opts[:allowed_roles]).map(&:to_s)
    FactoryGirl.create :user, roles: roles
shared_examples "a secure controller" do |opts = {}|
  let(:actions) { SecurityHelper.action_names(controller, opts) }
  let(:insecure_user) { SecurityHelper.create_insecure_user(opts) }
  context "without authenticated user" do
    it "doesn't allow access without signing in" do
      sign_out :user
      actions.each do |action|
        get action.to_sym, id: ''
        response.should redirect_to new_user_session_url
    it "denies access to non-allowed roles" do
      actions.each do |action|
        sign_in insecure_user
        get action.to_sym, id: ''
        response.should redirect_to '/'
shared_examples "a secure support controller" do |controller, opts = {}|
  include_examples "a secure controller", {allowed_roles: [:support]}.merge(opts)

I included an example of how to set it up for what I call the support controller.  All you need to do is give it the roles that are allowed and then it creates a user with every role except those.  Then in your controller spec, add this line:

it_behaves_like "a secure support controller"

Voilà! Now you know if anyone ever breaks the security in your controller.

As for the positive side of making sure that a good user can still get in, I just rely on the regular specs since any good test suite will hit every action at least once.

Time Traveling Servers

Ever wonder how you could start your server in a different time, like say 2 days ago.  The QA team was struggling with this for a while until my coworker came up with this ingenious way of using Timecop. In your environment.rb file in rails, add in this:

days = ENV['TIMECOP_DAYS'].nil? ? 0 : ENV['TIMECOP_DAYS'].to_i
minutes = ENV['TIMECOP_MINUTES'].nil? ? 0 : ENV['TIMECOP_MINUTES'].to_i + days.days + minutes.minutes

With that in your environment file, you can start rails server like this:

TIMECOP_DAYS=-1 rails server

Now for all intents and purposes it looks like you are exactly 24 hours ago.