Information Technology Dark Side

Struggles of a Self-Taught Coder

Information Technology Dark Side header image 1

How we used Slack to dramatically improve customer service response times

September 9th, 2015 · No Comments

For the last few weeks we’ve had a serious problem – we couldn’t keep up with customer support requests. Every day our lead time grew. When it hit SIX FREAKING DAYS I started to panic.

Fortunately, I’m a good panicker. I hired a truckload of really smart teenagers, put them through a crash course on TroopTrack, and they worked through the backlog. In a few days they were able to get the backlog back down to a level that wasn’t crushing just to think about.

We immediately started brainstorming ways to keep up. We had recently started using Slack for exception notification and we really liked it. It was far superior to email notification and it made it real obvious when things were going very wrong. We loved it. Someone suggested that we could do the same thing with help desk tickets. We have our own custom help desk app, so we can do whatever we want. I loved the idea and immediately started adding hooks between Slack and our help desk app.

Here’s a screenshot of a typical flow from Slack:


We have links back to actions in our helpdesk – a user can claim a ticket if they know the answer or they can escalate it if it requires development. Every time a user comments on a ticket the comment shows up in Slack.

There’s something about seeing user requests in real-time in our team communication tool that is very compelling. I find I want to click “Claim” before one of my intern does. And if it’s a serious bug, I am much more likely to hop on it right away when it comes in this way.

Integrating with Slack was super easy. I won’t describe how to do it here since the internets are full of examples. But I will say this – interjecting customer support requests into the heart of our virtualized team culture has been a total game changer for us. Where we were once lucky to respond in less than an hour even when we weren’t swamped it is now common for us to respond in five minutes or less. And that’s totally awesome.

→ No CommentsTags: Uncategorized

Five things I learned about testing by becoming a developer

May 14th, 2015 · 3 Comments

Testing software saved my (professional) life.
A long time ago I was totally stuck professionally. I was a project manager in the IT department of a giant insurance company that had absolutely no clue about freaking anything. I was miserable beyond belief. I wanted out. Out of project management, but most of all, out of corporate IT.

So I started testing software on the side for a friend’s company. I tested in the morning. I tested in the evening. I even tested on my lunch hour. Developer’s would deliver a story, I’d pull the code down locally, break it, and reject their story.

After about a year of this I was offered a full-time job by the company I’d been moonlighting for. I got the offer, wrote the shortest resignation letter ever, and handed it to my boss in the hall. I might have said “I’m outta here” or something like that. I think I also asked for my last two weeks off. That’s how bad I wanted out.

I tested full-time for the next two years and I loved it. All the corporate IT bullcrap was gone. We had less than two hours of meetings a week. We had a lot of freedom choosing what to work on and how to do it. If I thought a feature needed an automated test, I wrote it. If I thought it needed five test sessions, that’s what I did. I was my own man, and I was free. It was awesome.

Throughout this entire time, I’d been learning to program in Ruby in my free time as I built I found I liked that too, and I eventually became competent enough that people started offering me jobs. I turned them down, until one day it became obvious that the startup I worked for was sinking fast. I jumped ship and started writing code for my day job AND my night job.

That was 2011. I think. I’m bad with dates. It’s been a while. I’ve been writing and testing software every day since then. And I’m happy as can be. I have a hard time imagining my life any better than it currently is. Especially since we finished the swimming pool a few weeks ago.
2015-05-07 13.13.29

I owe it all to testing software, my gateway drug to a better life.

Gazillions of lines of code later…

My perspective on testing has changed now that I’ve written a lot of software, launching 1 – 2 new products a year. Here are five things I wish I’d understood then that I have only learned because I became a developer.

Writing software is real hard
Do you ever test a feature that fails in a way that is so obvious, so painfully stupid that you can’t help imagining what the heck the Roger was thinking when he committed? Roger is a freaking idiot!

I did. But I didn’t call the devs I worked with idiots, because they are all really brilliant programmers and I knew. But they still made really stupid mistakes sometimes, and I couldn’t help wondering how that happened.

A gazillion lines of code later, I know exactly how it happens. It happens in a million different ways. Here are a few:

  • An interruption occurs just as I’ve figured out how to fix a problem. Later when I come back, I confuse understanding the solution with implementing it, and I commit. DOH.
  • I code the happy path and test it. I work on the problem paths and get them working to my satisfaction, but break the happy path. I forget to re-test the happy path and I commit. DOH.
  • I mistake an edge case for the common case and implement the edge case. I don’t find out that I’ve chosen the path of pain until a tester does a better job of understanding the feature than I did.

These problems have simple solutions, like re-testing, ignoring the phone, and talking to product owners. I get that. It’s also super easy to make these mistakes, and even though I spent several years zeroing in on these mistakes by others, I’m not any better at avoiding them than the other developers I know.

It’s hard to test your own code

TroopTrack was a solo project for most of it’s history. I didn’t have anyone helping me with the programming on a daily basis until last summer when I got my first intern. We only finally hired a tester last week. So, for the past seven years, I’ve been testing my own code day in and day out. I’ve learned one thing from this: It’s really hard to test your own code.

When I test YOUR code, I think about things before I start. I read about the feature. I think about the stuff that has already been built and how they might interact with this feature. I consider YOU and what I know about YOUR programming style and weaknesses. And then I start to attack. I find flaws quickly because I know that YOU tend to focus on the happy path first and ignore the problem cases until the end. Or that you have a tendency to use a limited data set in your development environment. Or whatever. When I attack the code I attack YOU.*

The problem is, when I test MY code, I have already considered all those things. I read about the feature. I thought about the stuff that has already been built. I even thought about the mistakes I tend to make. It’s extremely unlikely that I am going to think of anything new the second time around, and so I don’t find the bugs YOU would find if you tested my code. I generally only find the bugs that are the result of the code not doing what I already coded it to do because I am too biased by my understanding of the solution to see the flaws that are obvious to YOU.**

Untimely testing increases the cost of fixing bugs dramatically
It’s common on some of my projects to be delivered one day and not be tested for 2 – 5 days. This is really frustrating, especially when the story is rejected. It adds an additional 15 – 60 minutes to the time it takes to fix a bug if it has been more than 24 hours since I worked on it. That’s money down the drain. I never understood this as a tester and I resented the way devs got frustrated when I chose other work over testing a recently completed story.

Programmers always feel stupid already
Whenever I hire an intern, I tell them how great programming is. Except for this one little thing – you get to spend the rest of your professional life feeling stupid. The only consolation is that you will feel less stupid than you did a year ago, most of the time.

I have spent hours staring at code, testing various scenarios, and poking sharp implements in my eyeballs because the stupid code was just not doing what I wanted it to do. And then I notice that I did something asinine, like misspelling a variable name. Hours of my life down the drain because i before e except after c.

That’s an extreme example, but less extreme versions of it occur every time I code. For me, programming is a process of reducing a complex thing into a couple of simple things. Figuring out what simple things are needed requires experimentation and failure, and when I finally figure it out I am embarrassed at the crooked, wasteful path I took to get there.

Skilled testers are way more valuable than I ever knew
Most testers can find bugs. Really skilled testers can communicate about the bugs they find in a way that helps me understand a few things:

  • How the result of the test varied from their expectations
  • Why this variation is important
  • What I need to do to see this problem for myself

Or, I guess you could just reject the story and add the very helpful comment “Doesn’t work”. That’s cool too. Because… skills.

Testing Skills Matter
Richard Bradshaw (@FriendlyTester) and I will be teaching a two-day testing skills workshop in Central London in the fall. If you would like to learn more about this, send me an email at

* Is that mean? I don’t feel like it is, but I frequently feel vindictive pleasure when what I know about a dev leads me to a bug quickly.

** Unless enough time passes between coding and final testing for me to forget how I solved the problem. That’s generally 3 – 7 days, which is way to long to leave a pull request hanging.

→ 3 CommentsTags: Uncategorized

Tips for making your integrated system a beautiful, majestic monolith

April 26th, 2015 · 1 Comment

The longer I do this, the more I agree with @dhh
If you haven’t seen it yet, you should watch @dhh’s talk from RailsConf2015. In it, @dhh introduces the notion that “monolithic” applications aren’t really bad in and of themselves and rebrands them as integrated systems. As I listened to @dhh talk I realized that I have grown to feel much the same way.

I’m proud of my monolith
I started building TroopTrack in 2008. I think it began life as a Rails 1.8 application, but I’m not entirely sure. We were not using git back then and the sad truth is I no longer have the repo history going back to day 1.

TroopTrack is a monolithic application. It’s huge. It has 125+ models and well over 200 controllers. The routes file is almost 700 lines. It’s really, really big.

I think it’s beautiful.

That’s not to say it’s perfect. TroopTrack has been my personal Rails education, and you can still see some of my more painful learning experiences in the code. There are parts of it that absolutely suck. I once gave an impromptu presentation I called “the worst code you ever saw” and I pulled it straight from TroopTrack. A thousand lines of pure misery, all in one file. There are pockets of code in TroopTrack that are so horrible I dread looking at them and hope I don’t pull a story related to them.

Warts aside, working on TroopTrack is fun and generally not that hard. In spite of its size, I still enjoy making changes and adding new features to TroopTrack. I don’t feel as if I am suffocating under nearly eight years of legacy code that restricts my every move and leaves me worrying about the unforeseeable side effects of every change we make. TroopTrack’s code is generally well organized, easy to understand, and fun to work with. In spite of it’s size, we can still turn on a dime and execute a new feature or a re-design of an existing feature at top speed.

For example, we recently added the ability to selectively override certain views to make them work better on a small mobile device. I investigated a few different approaches, experimented with them, picked one, then rolled out an initial release that dramatically improved our usability on mobile devices. It took me about ten hours.

About the same time, we started work on a mobile app. To support it, we need an API. So we started adding end points as the mobile developer requested them. Turns out, that was pretty easy too.

The point I’m trying to make is simple. Life with a monolith doesn’t have to be bad. @dhh doesn’t live in a world with a different set of rules than the rest of us mere mortals – if he can build a majestic monolith that is fun and easy to work with, so can I. And so can you.

Here are some things we’ve learned along the way that I think are helpful for creating an integrated system that doesn’t crush you as it grows in size and complexity.

Solve the real problems

This code base is monolithic. We need to make it less monolithic

I’ve said this. I’ve broken an application (not TroopTrack) up into a collection of engines just so it would be “less monolithic”. I’ve seen developers look at a code base and say “Ugh. Monolith”.

The problem is not that an application is monolithic. That’s like saying that a car is bad because it’s blue. Blue is just a fact. It’s not a moral imperative. The fact that a code base is big doesn’t mean it’s bad.

What we usually mean when we say that a product has become monolithic is that it frightens us. It’s big. It seems complex. It appears to be near impossible to understand everything it does. The sheer effort required to grok the code seems impossible to produce.

The first step in making a monolithic application majestic is to deal with this fear and stop blaming the monolith. Regardless of how you break a product up into pieces, a product that does a thousand different things (for good reasons) is going to take some time and effort to understand. This is not impossible. It just takes time and effort, and if you organize your code well and follow the rails way as much as you can, you can make changes to the parts without completely understanding every aspect of the whole.

Instead of blaming the monolith for problems in your product, blame the problems. Then figure out how to make them better.

Optimize for understanding
I went through a phase a few years ago where I tried to be really clever with my code. I tried to do as much as I could in a single line of code. For some reason I don’t understand, I also didn’t hit the return key very often. Maybe my text editor at the time had line wrapping or something, I don’t really know. Years later when I run into some code from my clever phase, the horizontal scrolling and long chain of commands really tick me off and I immediately make changes to make it easier to read.

There’s really nothing wrong with being clever. But if there are two otherwise equal solutions to a problem, and one of them is easy to read and the other one is clever, the easy to read solution is better.

The clever solution is only ever better than the easy to read solution if it offers some additional value beyond sheer cleverness.

If you optimize your code around being easy to understand you won’t need to understand everything the application does in order to work on it. This makes it a lot easier to deal with the fear that developers often experience when they get their first glance at the innards of a monolith. You want their first deep dive into the code to leave them feeling better, not worse. If a new dev pulls a story, does it, and says something like “that wasn’t as bad as I thought it would be”, you should consider that a victory.

Use namespaces to reduce complexity
In TroopTrack we have six different user controllers. Each one deals with users from a different perspective – from the view of our helpdesk staff, a customer, a partner, etc. This really represents the fact that TroopTrack is actually several different applications that share some stuff: we have a helpdesk, a mobile app, a partner app, and our customer app. To make things even more interesting, our customer app alone is pretty huge – it has two user controllers of its own, along with 150+ other controllers.

We use namespaces to isolate behavior logically. We’ve got a namespace for our helpdesk, our partner app, our API, etc. Within our main customer app, we have divided the functionality into five namespaces that reflect the user interface design: plan, manage, communicate, achieve, and share. These namespaces correspond to the way the application is organized visually. This makes life easier for us because if you pull a story that involves changing a feature that is part of our “communicate” set of features, you already know where the code for that feature is as well as how to get there in the UI.

Namespaces can reduce the brainpower required to work on your integrated system dramatically. I like my namespaces to represent the groups of functionality within my system because it seems natural to me for my namespaces to reflect the general categories of stuff the system does. You may find other ways that suit you better and I’d be interested in hearing about them.

Don’t get trapped in the default folders
Models. Views. Controllers. Helpers. Assets. Mailers. These are a few of my favorite things. But they aren’t all the things. We shouldn’t feel compelled to squeeze everything we do into one of these folders. If you have a thing that doesn’t really fit in one of these boxes, make a new box. You don’t have to put everything you make into one of these categories.

In TroopTrack we have some things that kick off processes that begin with an email to customers based on their partner affiliation, membership status, and other things. They get initiated by scheduled jobs managed by resque and it’s considerably more complex than just a query and an email. I started out by writing this as a class in our app/workers directory, but became frustrated by the number of things we had in there and wanted it to be less confusing. So I made a new directory, called storks, and I put these features there.

Yeah, storks sounds kind of stupid, but my thinking was that what we were doing was kind of like the mythological delivery of babies by storks. The arrival of the storks wasn’t just a delivery, it was the beginning of a whole new phase for the recipients. This was also the case for our customers – the arrival of these particular emails meant the beginning of a membership application or renewal process. Pulling them out of the Workers folder and creating their own place for them makes it a lot easier to understand where things are based on what they do.

You don’t have to put everything you build in one of the default folders off app. You can add more folders. With subfolders even! In hindsight, this seems obvious, and frankly, kind of a stupid thing not to know, but I see it a lot in myself and in other devs. If your code will be better organized and easier to understand by stepping off the template, do it. Do it.

Note: You don’t have to make a folder off of apps/ for things like storks. In this case I decided to do that because I felt they were distinct enough to belong on their own, but I could have easily put them in app/models/storks. We frequently do this for things that aggregate data from lots of models into a single view (i.e. reports) and for things that encapsulate complicated business logic.

Make it easy to get started
If you hire a new dev or accept a new contributor and the process to get your product up and running takes more than an hour you have failed. Don’t let this get out of control – never let your bootstrapping routine get so complicated that it becomes a deterrent to a new contributor.

Resources != models
Remember when everyone started to realize that fat controllers were a problem? A lot of us ended up with fat models after that, at least for a little while.

One of the reasons my controllers got fat is because I would try to use the same controller to deal with lots of different types of actions on a single model. In some perverse version of DRY, I would try to squeeze everything related to an achievement, for example, through a single achievement controller. My actions got full of conditionals, even to the point where I was sometimes redirecting different ways based on the things that were changed. It was a mess.

You can solve this problem lots of different ways. I sometimes solve it by just creating a different resource for the different types of actions I would take. For instance, we have the ability to record achievements for a lot of users at once. This used to be a big fat method on the achievements controller with a special action defined in the routes file. I made it better by creating a bulk achievement resource in my routes, then a simple controller to go with it, and a plain old ruby object to hold all the logic. This approach of moving complex logic into a PORO is well known, but the thing that I think we often forget is that our resources don’t have to be models. Refactoring this code to be easy to understand started with a single line of code in routes.rb:

resource :bulk_achievement

The point here is that we shouldn’t get trapped thinking that resources have to be models. It’s just the name of an endpoint for crying out loud. You can do whatever you want with resources, and they don’t have to correspond to a model.

Put the bad kids in the corner until you have time to deal with them
I mentioned some really bad code at the beginning of this post that is a thousand lines long. It used to be on our Troop model, and it made doing anything with our Troop model frustrating. The code works, in spite of itself, and we almost never need to change it. Because of what it does functionally (import data from a CSV file), and how it’s used (only my interns ever use it), it’s not really important that it be efficient or even 100% reliable. But it’s annoying. So I put it in the corner. I removed it from the Troop model and put it in its own class where it wouldn’t freak us out every time we changed the Troop model.

You might think this is a horrible practice. I admit it feels a bit underhanded to hide my bad code in the TroopTrack basement, but… it’s a pragmatic strategy. There is no compelling business case for making the code better. We wouldn’t make more money, we wouldn’t win more customers, and our product wouldn’t be more stable. In fact, there are hardly even any occasions that require us to read the code, much less touch it. So to the basement it goes. If we ever encounter a situation where that changes, we’ll deal with it. Until then… basement.

Be careful about dependencies
I love gems. They make our world a lot easier by giving us ready made features that we don’t have to build ourselves. The scope of gems that are available to a Rails developer is incredible. It’s awesome.

Gems totally suck. They get abandoned by their creators. They introduce dependencies on other things we might not want in our application. Sometimes those dependencies mean trouble when we try to upgrade rails, leaving us blocked and forced to either find a different solution, upgrade the gem ourselves, or wait.

Gems that do too little (asset gems that just add some javascript library for you) and gems that do too much (Devise) should be added to your application only with careful deliberation. You shouldn’t add a gem just because it does something you don’t know how to do. Look through the gem’s code and understand what it does. If you are adding a gem that only has a few lines of code… just write the code. If you are looking at a gem that requires contortions to make simple modifications, just write your own freaking authentication code. It’s not that hard.

Bite the bullet on Rails upgrades
TroopTrack started out as a Rails 1.8 application (I think). We’ve been through 3 major upgrades since then. Rails 3 was the hardest, partly because of self-inflicted wounds we earned by coupling the rails upgrade with a major redesign of TroopTrack. Don’t do that. Rails 4 was actually pretty pleasant. I’m over the moon about Rails 5 – Turbolinks 3 and Action Cable are going to be very important technologies in TroopTrack.

Falling far behind the current Rails version is disheartening and compounds the sense that a large code base can never hope to be majestic and beautiful. Don’t let this happen. It doesn’t always make business sense to be on the bleeding edge of Rails, but it’s never a good thing to fall more than six months behind a major release. Just bite the bullet and stay current. If you stay current on Rails, you will find it easier to feel good about your monolith and easier to enjoy events like RailsConf, where you will be able to walk away excited to use things like Turbolinks 3 and Action Cable in your real product, not just play with them in a prototype that will never see the light of day.

Target and repair bad code
Bad code is discouraging, whether it’s in a monolith or a micro service. When you find it, fix it. Don’t blame your overall system architecture for the fact that I got in a hurry and coupled some things that never should have been. Just fix it. Or yell at me until I fix it. Solve the real problem instead of imagining your problems would go away in a different design paradigm.

Thanks to @dhh and the Ruby and Rails communities at large
I love Ruby and Rails. Thanks to this amazing backpack of tools, I was able to leave a stupid soul-crushing occupation years ago, do work that I love, build a business that helps others, and bring some of my friends along with me. I am beyond grateful for the work others have done that have made my life so much better. So, here’s to you DHH, Matz, and everyone else who have stuffed my prepper backpack full of integrated system awesomeness: thanks a million. I love you all.

→ 1 CommentTags: Development · Uncategorized

This guy hated the crazy view logic all over his rails app. You won’t believe the simple trick he used to fix it!

August 22nd, 2014 · No Comments

Sorry, I couldn’t help it. This style of headline is all over the place. It’s tacky, so this is me mocking it a little bit.

Yesterday I blogged about a distinction regarding DRY and posited an example of view code that is better with repetitive code than DRY code. I won’t rehash that, so here’s a link.

In the end of the post I mention that I want to be able to create views that are named like this:
– menu.html.haml (default)
– menu.bsa_troop.html.haml (alternate view for Boy Scout of America Troops)
– menu.sa_group.html.haml (alternate view for Scouts Australia Groups)

Yesterday I converted a few really ugly views to use this approach, just to test out the idea that the view code would be easier to read and work on. I was really satisfied with how it turned out, but I still had to do add some logic to render the right view based on the troop type.

In this post I’m going to show you how I created a file system resolver to get rid of any sort of if logic like this:

if @troop.is_bsa_troop?
  render 'menu.bsa_troop'
elsif @troop.is_au_group?
  render 'menu.sa_group'
  render 'menu'

There are two things I needed to do to make this work:
1) Create a special resolver to find the views based on the troop type
2) Tell the resolver what troop type we are using

The code isn’t fancy or hard to understand, so I’m just going to show it to you.

class ApplicationController < ActionController::Base
  include ApplicationHelper

  around_filter :set_unit_type
  def set_unit_type
    Thread.current[:template_type] = @troop.try(:template_type)
    Thread.current[:template_type] = nil
class UnitTypeResolver < ActionView::FileSystemResolver
  def initialize

  def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
    unit_type = Thread.current[:template_type]
    if unit_type
      key = key.to_s + unit_type
      name = "#{name}.#{unit_type}"
    super(name, prefix, partial, details, key, locals)

Bam. menu.bsa_troop.html.haml gets rendered automatically if it exists and the troop is a Boy Scouts of America troop. If it doesn’t exist, it just renders menu.html.haml. This makes it super easy to create a totally different view of a feature for a specific type of troop, which makes my view code a lot easier to read and work on.

Thanks, @kofno, for helping me figure this out.

→ No CommentsTags: Uncategorized

Functionally repetitive code is best served DRY. Coincidentally repetitive code is best served simple.

August 20th, 2014 · 2 Comments

I’m starting to realize there is a difference between code that is functionally repetitive and code that is coincidentally repetitive.

Here’s an example of some functionally repetitive code:

class Admin::CoursesController < Admin::AdminController

  def index
    @courses = Course.all

  def show
    @course = Course.find(params[:id])

  def engagement
    @course = Course.find(params[:id])

  def new
    @course =

Functionally repetitive code is repetitive because of the functional nature of the activity being coded – for instance, finding a resource on a controller in all the RUD actions. That’s functionally repetitive. “Find the course” always means the same thing here.

Which is why that controller is better like this:

class Admin::CoursesController < Admin::AdminController
  before_filter :find_course
  def index
    @courses = Course.all

  def show


  def engagement


  def new
    @course =


  def find_course
    unless params[:id].blank?
      @course = Course.find(params[:id])

Drying this code up makes things simpler only because “find the course” always means the same thing at a functional level.

Not all repetitive code is functionally repetitive though. This is especially true in view code for me in TroopTrack where I have lots of conditional code based on the type of organization the user is in. I end up with lots of code like this haml partial:

- if @troop.is_tlu_troop?
  %li= link_to 'Advancement Instructions', '/assets/Advancement_Instructions_20140801.pdf', target: '_blank'
%li= link_to "#{achieve_title} Overview", achieve_root_path
- if @can_edit_achievement_records || @can_view_achievement_records
  - unless @troop.is_troop? || @troop.is_venture_crew?
    %li= link_to 'Record Individual Progress', [:new, :achieve, :individual_progress]
  - if @troop.is_tlu_troop?
    %li= link_to 'Record Progress (Bulk)', [:new, :achieve, :bulk_achievement]
  - else
    %li= link_to "Record Progress (Bulk)", record_progress_achieve_workflows_path

  - if @troop.bsa?
    %li= link_to "Print Advancement Report", advancement_report_achieve_workflows_path
  - if @troop.bsa? && @can_use_turbonet
    %li= link_to "TurboNET Advancement Report", [:new, :achieve, :e_advancement_report], {'data-no-turbolink' => true}
    %li= link_to "TurboNET Roster Import", [:new, :achieve, :turbonet_import], {'data-no-turbolink' => true}
  - if @troop.is_ahg_troop? 
    %li= link_to "TurboNET Advancement Report", [:new, :achieve, :ahg_advancement_report]
    %li= link_to "TurboNET Hugs Reports", [:achieve, :hugs_reports]
  - if @troop.is_troop?
    %li= link_to "Print Blue Cards", blue_cards_achieve_workflows_path
  - if @troop.is_troop?
    %li= link_to 'Board of Review Worksheets', bulk_board_of_review_achieve_users_path
  - unless @troop.aidmatrix?
    - if @troop.is_tlu_troop?
      %li= link_to 'Purchase Completed Awards', [:new, :achieve, :award_order]
      %li= link_to 'Past Award Orders', [:achieve, :award_orders]
    - else
      %li= link_to 'Shopping List', shopping_list_achieve_workflows_path
    %li= link_to 'Print Award Cards', award_cards_achieve_workflows_path
    %li= link_to "Print Agenda by #{scout_title}", agenda_by_scout_achieve_workflows_path(:format => :pdf), :target => '_blank'
    %li= link_to "Print Agenda by #{subunit_name}", agenda_by_level_achieve_workflows_path(:format => :pdf), :target => '_blank'
    %li= link_to "Present Awards", present_awards_achieve_workflows_path

  - if @troop.is_troop?
    %li= link_to 'Hours, Nights, & Miles', trackables_achieve_users_path

I don’t like this code much at all. All those conditionals based on the type of troop we are looking at makes it hard to read and to think about, but the first alternative I think of involves creating a different partial for relevant type of troop. We support seven different types of troops in TroopTrack, so the idea of potentially having seven different partials with big swaths of them being the same made me cringe a bit at first. But the more I work on TroopTrack, which is now in its sixth year, the more palatable the idea has become. I now think it’s better than what you see above, especially if I introduce some conventions to make it easier, such as including the troop type in the partial file name, like this:
– achieve_menu.bsa_troop.html.haml
– achieve_menu.bsa_pack.html.haml
– achieve_menu.scouts_au.html.haml
– achieve_menu.ahg.html.haml

That makes the intent extremely clear, and I could use interpolation to render the right partial with a single line of code.

To me, that code may be repetitive, but it’s a lot easier to reason about and to work on. DRYing it up, at least in the way I originally did it, only makes it worse. I think the reason DRYing it up isn’t helpful is because this code is only repetitive by COINCIDENCE. By this, I mean that the features that are common are not common due to something functionally intrinsic about them, but just because they happen to share some common needs.

I mentioned this realization to @kofno and here is what he said. I like his perspective:

I think you’re having an important realization about the intent of DRY. It’ s not about repetitive code, but it’s about having a single canonical place for some piece of system information.
Whether that is how to render users, or what makes a valid course, etc.
Drying up things that change together is what’s important.
If you try to dry things that are orthogonal but only look similar, you’ll be miserable.
For removing repeating code patterns and getting rid of boilerplate, that’s what macros are for (provided your language supports them). Ruby kinda does w/ metaprogramming.

Like @kofno, you might have had a “well duh” reaction to all this. That’s cool. I’m learning…

→ 2 CommentsTags: Uncategorized

Coding without Caffeine

July 28th, 2014 · No Comments

Best Sleep EVER
I woke up this morning at 6:00 am feeling totally awesome. I slept like a log last night, better than I’ve slept anytime in the last six months. Shannon tells me kids came in and out of the room, talking, even snuggling, and I didn’t even roll over. It was a deep, dreamless sleep and I feel freaking great right now.

I quit caffeine 2 1/2 days ago.

Wait, why!?!?
I know right?

Caffeine is a huge part of the world’s culture, especially coffee, especially in the morning. Quitting caffeine is a very counter-culture thing to do, but that’s not why I did it.

I quit caffeine for four simple reasons:

1) It makes me grumpy. When I drink caffeine regularly I am less patient with others, especially my kids. I am more inclined to snap at them than when I am caffeine free.

2) It erodes my ability to focus. I wish I could cite the talk where I learned about this, but I can’t remember. I think it was at indy.rb. Maybe one of my four readers will remember. At any rate, he was talking about the importance of knowing when our focus is best and working on hard problems then. He also mentioned that we should avoid caffeine until after this period because it makes focusing more difficult. I experimented with this idea prior to quitting caffeine altogether and found I was better able to solve hard problems if I postponed my morning Dr. Pepper until after I had worked on them. Admittedly, this is hard to prove in a scientific way, but since it doesn’t harm me to not drink diet soda I don’t really care. Even if it’s just a Dumbo’s feather, I’m still flying.

3) It messes up my sleep. This is something that is hard to observe while I am drinking caffeine, but is obvious every time I quit (I’ve gone years without caffeine at various times in my life). I sleep much better without it, all other things being equal.

4) It’s addictive. I don’t like being addicted to things. It’s bad enough that I am a food addict, but being a diet soda junkie also makes me feel a little depressed.

There are other reasons too. Drinking a lot of diet soda dulls my taste buds. It’s also generally pretty bad for you and, counter-intuitively, increases feelings of hunger. Caffeine also aggravates acid reflux, which sucks.

Withdrawal Symptoms
What’s it like to quit caffeine cold turkey?

The previous time I quit caffeine I had a horrible migraine for two days. During that time I had to interview a job candidate and in the middle of the interview I asked for a five minute break so I could go throw up. The migraine was that bad.

After two days I had a dull ache in the front of my brain for about three days.

It sucked.

This time I didn’t have a single migraine, but I quit differently. For one thing, I planned it better. I had my last diet soda at noon on Friday and immediately took some ibuprofen. I continued to take ibuprofen regularly on Saturday and Sunday.

I also paired my de-caffeination with a 3-day fast. During this time I drank only water (mostly). I started it on Thursday night and didn’t eat again until yesterday afternoon. I did this mostly because my parents and my little brother did it, based on research my oldest brother did (I have 4 brothers), and I can’t cite any research personally. But they did it and said it made them feel pretty great and changed the way they felt about food in good ways.

I was worried it would aggravate the withdrawal symptoms, but I think it had the opposite effect. I say this because at the time I quit I was drinking twice as much Diet Dr. Pepper as the time quitting rendered me useless for two days.

Coding without Caffeine
So, does it make my code any better? It’s hard to say, this time around, since I only quit 3 days ago. I don’t see how it can make my code any worse.

Heh. That made it sound like my code is as bad as it could possibly be. You’ll have to ask @kofno if that’s the case, I don’t think it is. I just don’t see how not being impaired by a stimulant could have a negative impact on anything once the withdrawal is over.

In the past I have found that I think more clearly and am distracted less easily without caffeine. I’m also less irritable and more inclined to be helpful to others.

About the 3-day Fast
I was 290 pounds when I started it and I ended my fast at 282 pounds. I plan to repeat the fast once a month for three days forever, based on my experience this weekend. According to my family members who have tried it, there are medically validated benefits from a regular fast, including improved immune system and lifespan. As I said before, I have no idea, but I belong to a smart family so I’m just going with it. Here are a few things I observed during and after my fast:

1) I craved fruit. We went grocery shopping during the fast and I was surprised at what made me salivate. It wasn’t candy, chocolate, or ice cream. I really wanted to eat the fruit.

2) Rich foods make me feel sick. I had a slice of cheesecake for my daughter’s birthday and couldn’t finish it. This is unheard of – I could normally eat three or four slices.

3) I needed salt. Next time I will take salt tablets. This time I just added salt to my water. Ick.

4) My stomach seems to have shrunk. I ate a smaller than-normal dinner on Sunday at the end of my fast and didn’t binge. I felt full.

5) Food tastes better. I think this is partly caused by my cessation of diet soda, which messes with my taste buds.

6) It changed the way I felt about food. I found myself imagining really good meals. Not fast food, or restaurant food, but homemade food from the cookbooks I have collected but rarely used. It made me want to cook that food.

7) It changed the way I feel about the poor. Starving isn’t easy. With enough water, it’s not terrible, but it’s hard to go without food for three days. This made me more sympathetic towards those people for whom the source of their next meal is not a certainty.

Your mileage may vary
I’m not saying you should try either of these things. I’m not a doctor and, as I have mentioned, I didn’t even bother to research any of this before embarking on my own experiment. You may find that none of this applies to you.

→ No CommentsTags: Uncategorized

Interns at TroopTrack

July 7th, 2014 · 1 Comment

Hiring IFL (Intern for Live)
Until recently, we really struggled to provide consistent customer service. Sometimes we were awesome – customers would put in a ticket on a weekend in the wee hours and would get a response right away. Other times… not so great. It was hard to provide consistent customers service when it was just Shannon and I and TroopTrack was growing so rapidly that it was clear we couldn’t do it ourselves. Things got worse when Shannon had to take a leave of absence for a family crisis. We soon found ourselves staring at more than a thousand open help desk tickets. It had gone from kind of bad to horrible.

During this time we experimented with hiring free-lancers to help with customer service. These were typically people with experience in scouting who thought they had extra time. We would train them on TroopTrack basics, then expect them to answer questions. This sometimes worked okay, but never great. The biggest problem was consistency. No one had a set schedule, so we never knew when someone would work. People always seemed to be busier than they thought.

We were feeling pretty desperate, and then one day I thought of my nephew Spencer who was due to return home from a two-year sabbatical in Brazil and would have five months at home before he went back to school. He is smart, technical, and needed a job to pay for his return to school. By smart, I mean super smart – he has a full-tuition academic scholarship to an excellent university.

I hired Spencer for $10/hour, forty hours a week and put him to work on the help desk. I gave him a Macbook Air, set up a local environment so he could run TT locally, pointed him at the queue of questions in the help desk and said “Figure it out”.

And he did. He occasionally asked us questions, but for the most part he used his brains and curiosity to become an expert user in a very short time. Every day, the first thing he does is answer every new help desk ticket. As a result, our customers get a response within a business day. This appears to have affected our conversion rate from trial customers to paying customers in a good way:


Two months of data is hardly conclusive, but the early indications are good that we are achieving a more consistent conversion rate than we have had in the past.

Our second intern, Coleman, starts tomorrow. Spencer is going to provide most of his training.

We call Spencer IFL, short for Intern for Life, and pronounced ‘Eifel’.

Here are some details about our internship program that I think may be helpful to other bootstrappers who are considering using interns.

Our interns all start at $10/hour. The most they can earn as an intern is $15/hour. I give them a $1 raise ever 4 – 8 weeks if they perform well until they hit the max. Once they hit the max, they are stuck there until they become an Apprentice.

An apprentice can earn up to $25/hour. To become an apprentice, an intern completes a special project that demonstrates an aptitude and passion for programming as well as a basic understanding of important programmer topics like SCM, TDD, etc. Once they complete their project they present it to the three C’s (CEO, CTO, and COO) and we decide collectively to promote them to apprentice. We don’t have any apprentices yet, but Spencer is working diligently on his project. I mention this to illustrate two things 1) it’s theory and 2) we have a plan.

An apprentice can eventually become a programmer. To become a programmer the apprentice has to achieve competency in our technology stack and be able to work relatively independently to solve problems and create features. A programmer can earn up to $50/hour.

A TroopTrack employee can progress through all of these stages as a part-time employee, which means that our interns can continue to work for TT after the summer is over and they start back in school.

The gist of all this is that an internship at TroopTrack is a good opportunity. It is totally possible that a sophomore or junior in college could start as an intern at TroopTrack and be a programmer by the time they graduate, finding themselves in a position where their earning potential is considerably higher than their peers.

Interns are young. Spencer is very smart and mature for his age, but he’s still a kid. It’s important to establish a set schedule and expect interns to keep it. They need to understand that consistency and reliability are important and that their continued earning growth is dependent on demonstrating those qualities. I have been very frank about this with IFL and will have this very conversation with IFL #2 tomorrow.

Assigning Tasks
Spencer’s primary responsibility is the help desk. But he also answers the phone, changes the trash, vacuums the office, and hauls stuff from my truck up the stairs to our office when I need him to. We also expect him to advance his programming knowledge, fix bugs, and add new features to TroopTrack that are within his wheelhouse. We give him pretty wide control over what he works on in the same way that my parents did: “You can play with your friends when your chores are done.”

This means simply that he needs to get our helpdesk back down to inbox 0 every morning before he does anything else. After that, he can learn ruby, fix bugs, or work on his apprenticeship project.

Establishing these priorities has been important – they mirror the priorities of our company and they create a healthy incentive to do what matters most NOW before moving on to activities with a more speculative value.

There are two types of luck:
1) Sheer luck, like winning the lottery or dying in a plane crash.
2) Exploiting a chance opportunity for which you have prepared.

Spencer is awesome, and I don’t deny that he is a lucky hire for us. But it is luck #2, not luck #1. Our experiments with freelancers, our discussions about career progression, and our attempts to manage the helpdesk ourselves put us in a position to fully take advantage of the fact that a very smart kid with nothing to do was within arms reach.

There was still some luck involved and I shouldn’t pretend that I know a lot about hiring interns. There are a few things I think are important.

1) You need to present a learning opportunity. Interns are students – their career is learning. If they aren’t interested in a learning opportunity you have dodged a bullet by not hiring them. If you don’t have a learning opportunity to offer you won’t get the best candidates.
2) Hire someone who wants to learn to program. This is not the same thing as hiring a CS major. People choose majors for a rainbow of reasons – don’t assume that someone who is studying CS wants to learn to program or that someone who is study Ancient Roman Literature doesn’t.
3) Hire someone you know if you can. I have known Spencer his entire life. I know his pros and his cons. I knew before I hired him that he would need phone coaching. I also knew that he would soak up programming concepts like a sponge.

We hired Spencer and handed him two books and a bunch of web sites. The books were Learn to Program and Agile Web Development with Rails 4. I told him to work through the books every day AFTER he finished the helpdesk. Within a week I could tell that Spencer had an aptitude for programming. The web sites we handed him were about git and github.

→ 1 CommentTags: Uncategorized

The Bootstrapping Thing I Suck Most At

June 13th, 2014 · No Comments

Benjamin Franklin said

So convenient a thing it is to be a reasonable creature, since it enables one to find or make a
reason for anything one has a mind to do

I’m not being a reasonable creature, and it’s darned inconvenient

Last night I stayed up playing Civ 5 until 2:00 am. I didn’t enjoy it as much as I should have because I felt guilty that I wasn’t working on my bootstrapped business.

Playing is healthy and we need to do it. I shouldn’t feel guilty about it. I know this is true in a academic sort of way, but I can’t seem to integrate that into my nature.

This is in spite of tremendous evidence in my business that doesn’t even include the experiences of other bootstrappers who have successfully built product businesses without killing themselves. And yet, when I “only” work 50 hours in a week I feel guilty. This has got to change.

The Case Against My Work Guilt
Let’s recap the evidence proving that
1) I don’t need to work 80+ hours a week anymore (if I ever did)
2) That I don’t need to feel guilty about goofing around

  1. In 2009 the partnership that started TroopTrack fell apart and I spent several months dealing with the conflict – first I bought out a partner, then I dissolved and re-formed the company, then I spent a month wallowing in depression and emotionally regrouping, all the while ignoring the day-to-day operations of the business. Our subscriber base didn’t really grow, but hey, we’re still here.
  2. In late 2010 I hurt my back very badly. I struggled to walk for a while and spent six+ months walking with a cane. I made almost no changes to TroopTrack during this time and ignored all but the most critical customer requests. Several customers called me to ask if I was okay. I think they worried that I had died. Here’s the rub: Our Subscriber base continued to grow
  3. In late 2013 my sister-in-law moved in with us. She had terminal cancer and Shannon became her full-time caregiver. Shannon had previously been operating the help desk and had been rocking it. With her gone and TroopTrack growing at an unprecedented rate, we fell far behind and didn’t catch up for more than six months. Guess what? Our subscriber base continued to grow

The Verdict: Guilty of Stupid Guilt
Great. Now I have to feel guilty about feeling guilty when it happens.

Just kidding. Hopefully putting this down in the open like this will make me feel better about it.

The worst part about this guilt is that it’s totally unreasonable. There is no need for me to work that hard anymore. I have Ryan, Spencer, and Shannon backing me up. We are paying the bills and growing like a California wildfire. It’s stupid to feel guilty about not doing something I don’t need to do.

The fact that TroopTrack’s customer service/support has been on life support a couple of times without negatively impacting the long-term viability of the business should not be construed as a belief on my part that I can just ignore the business and it will be fine. That’s stupid. The point here is that there is absolutely no reason for me to think that I have to work 24/7 just to keep the business growing. There is way too much evidence for that belief to persist any longer in my consciousness. It’s time for it to go.

Be free Dave.

→ No CommentsTags: Uncategorized

Bootstrapping sucks. Everyone should do it.

May 9th, 2014 · No Comments

Bootstrapping Sucks
Winston Churchill famously said the following after losing power following World War 2:

Democracy is the worst form of government, except for all those other forms that have been tried from time to time.

After six long years of bootstrapping, I feel much the same way. Bootstrapping sucks. It’s freaking hard, at least the way I did it, and it’s full of low-points that require you to learn important lessons the hard way.

The hardest thing I’ve had to learn is how to be the CEO. Six years ago I didn’t know Jack about running a business. In 2008 I literally believed that if I built a web-app for managing Boy Scout Troops I would sell 10,000 subscriptions immediately and be rich overnight.


It took four years to get 100 subscriptions. Four long years of working a real job with real demands, then working another 20-40 hours on nights and weekends. For FOUR YEARS. Do the math on the return on that investment real quick. Actually, don’t. It’s too depressing. 100 subscriptions is only about $9000 in revenue. There’s no way that’s a good investment.

That’s the first thing that sucks about bootstrapping:

Reality sucks.

Every bootstrapper has a moment where they realize that this is going to be hard, and lots and lots of bootstrappers don’t make it past that moment.

I remember that moment explicitly. I was sitting in a Qdoba in Indiana in August 2009 talking with some guys about TroopTrack and I suddenly realized the truth. This was an endurance race, and it was a race no one has to finish and no one ever wins. You only lose. All you have to do is stop running and you lose. But there’s no finish line. IT NEVER FREAKING ENDS.

It’s easy to see how that could be a depressing moment. I almost threw in the towel. My product was crap. My business wasn’t growing. My partners were hostile and wanting out. My day job was pushing me hard. My wife was sick and I had gained a crap-ton of weight.

Shannon wouldn’t let me quit, and she helped me see a simple truth:

All we have to do is never quit

That subtle viewpoint shift was important. Instead of seeing bootstrapping as an endless race that I could never “win”, I learned a simple truth: I didn’t need to win. All I had to do was never quit.

Here’s the next thing that sucks about bootstrapping a web-based business:

The Toobs NEVER Sleep
People use TroopTrack at all hours of the day, 7 days a week, 365 days a year. And they have problems. And questions. And feature requests. They expect me to help them, to answer their questions, to fix bugs, and to add the features they ask for. I have customers who, if I don’t respond to a help desk ticket within an hour on a Sunday afternoon, will post their question to my Facebook page, send me an email, and call my cell phone.

Okay, I’m exaggerating a little, but it sometimes feels that way.

TroopTrack has been growing 250% per year since 2009. That’s not a big deal when you start with 2, at least for the first four years. For a long time I was able to keep up with everything and excellent customer service became the cornerstone of our reputation.

Then I broke my body. Well, at least that’s how it felt. I slipped a disk. It was horrible. I could barely walk, even with a cane. I couldn’t even sit up to work, and laying on my back to code was only marginally workable because of the leg spasms that attacked me every few minutes. I was barely able to keep my day-job commitments, much less my TroopTrack commitments. It was months before I was healthy enough to do my day job well and to work on TroopTrack.

In the meantime, TroopTrack hadn’t stopped growing and the requests for help kept coming in. I started to get emails asking if I was still in business. Long time customers called me to see if I was still alive. I had no choice but to tell them the truth and beg for patience. It was humiliating and, sadly, not the last time it would happen.

It happened again last year, when my sister-in-law and her family moved into our home for the final stages of her battle with cancer.

During that time TroopTrack was growing more than ever, and the help desk tickets weren’t slowing down. We went from handling it to completely failing at customer support overnight. By the time the family crisis was over we had 1700 open help desk tickets.

Here’s the third thing that really sucks about bootstrapping, and the last one I’m gonna mention today:

Your family will hate it
Bootstrapping a business is like having a mistress, but without the extramarital sex or intrigue. Or, at least I think it is. I’m not that kind of guy. At any rate, it certainly comes with the guilt and jealousy that I imagine cheaters feel.

Shannon used to describe TroopTrack as the other woman. She was committed to it, she believed in it, and when I wanted to give up she was the rock that kept me going, but she also resented it, and so did my kids. Frankly, so did I. I didn’t want to work all the time. I managed to survive that way for the first five years, but by 2013 I was burned out. I wanted to play. I wanted to go to the movies without worrying about the ****ed distribution list server falling over. That thing goes down and I get irate people within an hour. I hate email. I wanted to go on vacation and not think about TroopTrack for two weeks a year.

All of this was completely impossible, and the guilt was horrible.

Dad, you never play with me anymore.
Jake, age 5

Boom. Cold knife in the heart.

All My Problems Were Solvable
I already talked about solving the first problem (Reality sucks), but the other two problems had one solution: Hire Shannon.

She was looking for a way to earn some money on the side and was talking about getting a part-time job and one day the obvious hit me hard enough for me to recognize it. So I hired Shannon to be the COO. I paid her crap (and frankly still do!) and asked her to get the help desk under control. She was happy to get the money and to have the freedom of a job she can do from home on her own schedule (the toobs never sleep!).

The best part of all is that TroopTrack stopped being the other woman. SHARING MY TROOPTRACK TROUBLES WITH MY SPOUSE WAS THE BEST BUSINESS DECISION I EVER MADE. Almost overnight this:

The whole family is sitting around watching a movie and you have to be on your laptop the whole time!?!?
Shannon, Pre-COO

became this:

You’ve seen this movie before and there are five help desk tickets I need your help with, hint hint.
Shannon, TroopTrack COO

I can’t tell you just how awesome and gratifying it is to have Shannon engaged in our business. Talking about TroopTrack used to be boring to her. She would listen, but not really engage, and the subject would get changed at the first opportunity. Not anymore. Now she schedules business lunches with me. She is in the details of the business. She’s excited about where it’s going, and she’s making it better.

This is a big freaking deal Mr. Bootstrapper.

Everything Else Sucks More
Sure, the last six years have been hard. But look at this:


You’ll have to click it if you want to be able to read it.

That’s pretty awesome, IMO. Sure, it took six years to do it, but I have enough subscribers now that I could live completely off TroopTrack. And the growth curve is promising – if we don’t stop running and keep solving problems as we encounter them, we will someday have 10,000 subscriptions. And hey, that’s a crap-ton of money.

But what does this have to do with everything else sucking?

It’s simple. I want you to understand what I currently have because I bootstrapped. That chart is MINE (and Shannon’s). We own TroopTrack outright. Even if TroopTrack leveled off today and stayed level, we would still have the financial equivalent of a winning lottery ticket that pays out $100k every single year.

At this very moment we are a financially independent family. We can’t be fired, laid off, downsized, whatever. We control our own destiny.

So let’s talk about what the other options would have given us and whether or not I would have avoided the three things that suck most about bootstrapping.

VC Backing
First of all, VCs expect you to work like a bootstrapper. So, right off the bat, I would still have the problems associated with working all the time, but with a nasty new twist: if I became temporarily incapacitated because of health or crisis they would leverage that to take more of the company away from me.

There are all sorts of unhealthy dynamics associated with venture capitalism that are well documented elsewhere, so I’ll skip those. Worst of all, I wouldn’t be able to chart my own course. I’d have to deal with VCs and their opinions. No thanks.

Secondly, having VC money doesn’t make the transition from fantasy to reality any easier. In fact, the presence of other people’s money can postpone that transition, all the way up to the day you shut down. When you still have a pile of cash you don’t have to face the facts.

Finally, the toobs still never sleep. If I had piles of money I could have just hired people to worry about the customers. That detachment early in a product company from the customer is not good. That’s how you learn – talking with customers is a critical part of my learning experience. Sure, there are ways you can structure support so that you aren’t totally detached from it, but doing so would have brought other troubles and problems to solve that I didnt’ have to go through as a bootstrapper.

So what if I had taken VC money to start TroopTrack, where would I be?

Out of business. I guarantee it. There have been numerous attempts to do this and every single one ended the same way. Dead. And I think I understand why.

It’s because this market is a slow mover. It doesn’t matter how awesome your product is – it takes years to get this market to change. The purchase cycle of scouting software is at least a month, and the effort for a scouting unit to switch from one package to another is huge. Even if the technology makes switching easy, the social costs of switching are super high. First you have to convince the committee. Then you have to win over the parents. It’s hard. People don’t want to go through it unless they have to, and they don’t want to mess around with software that might not be around tomorrow. They take the process very seriously – we frequently get emails from customers that read like a million dollar RFP. For a $99 product.

There’s no VC in the world that has the patience for that. Even with a million dollars it would have taken six years to get 1000 subscriptions.

The Other Option
The other option I want to discuss is doing nothing. Sure, I would have had an easier six years, probably. I might still be at Liberty Mutual, slogging away at putting a percentage of my blood sweat and tears into a 401k that might someday be able to pay out $100k a year when I am old.


The One Thing I would Change
This year we made a big change in the way we bootstrap. I quit my job and started consulting. I landed enough contract work to also hire Ryan Bell. We structured our contracts so that Ryan only has to consult for 30 hours each week and he has time to work on TroopTrack. I still work a lot, but not as much as in the past.

I wish I’d done this sooner. I don’t think I could have made it work prior to 2011 or so because I still had a crap-ton of things to learn about Ruby on Rails development (I was a project manager who hadn’t programmed in years when I started TroopTrack). It’s really hard to hold down a real programming job and launch a product company on the side.

So, if you can, start a consulting company along with your bootstrapped product company. Then structure your contracts so you can live off of 20 – 30 hours per week of consulting. Working as hard as I have done sucks big time and I don’t recommend it.

Everyone Should Bootstrap
I’m so glad I built TroopTrack this way. It feels great to still have complete control of the product when it finally starts to get traction. It’s been super hard and I have had to think long and hard about the answer to THE question:

If you knew in 2008 what you know now, would you still launch TroopTrack as a bootstrapped company?
Everyone I Know

Heck yeah I would. And you should too.

If you want to start a business, bootstrap it. If you want to start a business that can’t be bootstrapped, START A DIFFERENT BUSINESS. It took me four years of evaluating different business ideas before I settled on mine. If you can’t bootstrap your idea, toss it until you find one you can. There are tons of market gaps out there that can be invaded by small businesses. If you look long enough you will find one that is right for you.

Do it.

Gratuitous Acknowledgements
PS. This may sound gratuitous, but I don’t care. TroopTrack was inspired by the success of 37Signals and is an outright attempt to emulate and imitate them. Even though I’ve never met a single one of them, I owe them my thanks. So here it is: Thanks a Crap Ton. I love you guys.

PPS. Also, thanks to you Shannon and my kids. I love you more than TroopTrack. :)

PPPS. I’d be screwed without @kofno. Thanks man.

Other Bootstrapping Posts

Here are a few of the hard lessons I’ve learned over the years:

→ No CommentsTags: Uncategorized

Finally! An excuse to override method missing!

December 2nd, 2013 · 1 Comment

I load a lot of data into TroopTrack from CSV files by mapping fields in the CSV file to active record. Most of the time I am importing data from my competitors using CSV files they provide (and control the format of). In the past I have tended to write pretty sucky code for doing this where I build a hash of values that I then use to update active record, like this:

CSV.parse(@file_to_import, { :col_sep => "t" }) do |row|
  household_hash_1 = {
          :name => row[25],
          :line1 => row[27],
          :line2 => row[28],
          :city => row[29],
          :state => row[30],
          :zip_code => row[31]

This code seemed okay when I wrote it, but then I learned that at least one of my competitors would add a new field to the CSV file every couple of months, which meant I had to redo the mapping of the attributes. PFFT.

Last week I started a project loading data into ActiveRecord from Microsoft SQL Server. There are about a hundred different tables that I need to transform and load into TroopTrack. Needless to say I wasn’t feeling very thrilled about using the approach mentioned above. The mere thought of THOUSANDS of lines of code mapping a hash to a CSV file makes me want to vomit.

Method Missing to the Rescue
If you don’t know about method missing you’re probably not reading my blog, so I’m not going to explain. If you wandered here somehow with no ruby or rails experience and still care, just google “override ruby method missing”.

All the code below does is let me treat a row from a CSV file more like an active record entry, so that I can write mapping code that is more readable and avoid thousands of lines of that crap above.

In other words, given a row from a csv file with a header that includes “last_name”, I can write code like this:


That’s pretty handy.

class DataGenius
  def initialize(filename)
    @data_items = []
    rows =[Rails.root, 'db', 'data', 'csv', filename].join('/'))
    rows.each_with_index do |row, i|
      if i == 1
        @header = Hash[*{|val, idx| [val, idx]}.flatten]
      elsif i > 1
        @data_items <<, self)

  def header 

  def data_items

  class DataItem
    def initialize(row, data_genius)
      @row = row
      @data_genius = data_genius

    def row

    def method_missing(meth, *args, &block)
      if meth.to_s =~ /^get_(.+)$/
        p $1
        super # You *must* call super if you don't handle the
              # method, otherwise you'll mess up Ruby's method
              # lookup.

→ 1 CommentTags: Uncategorized