On Software Development and Fuck-Ups

I posted on Twitter earlier today something from Timehop. For whatever reason, historically, around April 14th, I just seem to always fuck something up. I don’t know why. There’s nothing significant about that date to me, but for three years in a row, I have managed to do something every year. Possibly for more than just 3 years, but maybe then I just sheepishly hid in a corner then.

I reserve the word “fuckup” for things that have painfully huge aftershocks. For perspective:

In 2014, shortly after joining Treehouse and implementing a way for our support team to issue refunds through our admin tools, I shipped something to production that completely broke that refunding tool for invoices paid via PayPal. This was humiliating for me. I was sure everyone I worked with thought I was an idiot.

In 2015, I upgraded a large portion of our billing library to a new version of Braintree’s API and while doing so, added a client-side validation for postal codes that completely blocked out British people (fortunately we noticed this almost immediately). I felt so incredibly awkward and frustrated with myself. How dare I screw up a regular expression? Who in the history of the world has ever done that?

In 2016, I accidentally hit backspace on a portion of a WHERE clause in a query and, as a result, ended up sending an e-mail to a large number of people who shouldn’t have received it. This bit me hard. All it took was a single keystroke. After reviewing the query multiple times, I failed to review that one. last. time. before hitting “export to CSV.”

If you look at those three stories together, you might decide I’m a really shitty developer. Those are very painfully embarrassing mistakes to make, but I won’t deny that I’ve learned something from all three of them.

I’m in my 12th year of my career as a software engineer and I share these stories because it’s taken me 12 years to understand that owning your fuck-ups is more valuable than trying to save face. There is something suspicious about a person who has made it over a decade without fucking up. All of the developers I respect the most have a story or ten. They laugh at them in hindsight. And so do I. I don’t think, “what a dumbass.” I think, “Oh man, yeah, I feel you.”

I thought for a very long time that if I could stealthily fix a problem without outing myself, that I should. I feared the shame of people losing trust in me to be able to do something correctly. I feared that they would talk about me behind my back. That they’d be angry with me. I’m a very sensitive person and very self-critical already, so making mistakes can take a huge personal toll on me, so much that I sometimes will cry because I’m so embarrassed.

I can’t say I don’t cry when I screw up, but I’ve since learned that people will trust you more if you are open and honest about your mistakes, especially when you are earnest and heart-felt in your mission to remedy what you’ve done wrong. Would it be nice if you hadn’t made a mistake? Sure, but good luck with that.

So, I’ve recently resolved myself to a few different things. When I know I’ve screwed something up, I:

    • Immediately notify other people that I feel should know.
    • I take a step away for a moment and clear my head. If I’m distracted, I’m not going to be able to fix the problem.
    • I make an action plan. I think it’s easy to panic here and try to fix something super quickly and instead stir more trouble into the mess.
    • I document the problem. Very thoroughly. I try to use laymen’s terms so that anyone can understand what has gone wrong.

I reflect back on my mistake. It’s mine. In a year’s time, it’s going to be a funny story. Right now, it’s a moment to learn how I can prevent it.

Value your fuck ups. They make you who you are.

What the Hell Should I Stub in My Tests?

Until very recently, one of my job responsibilities at Treehouse was serving the role of a mentor to a junior developer. It was a role that I appreciated because it sometimes called to question my own understanding of things that I have always assumed I knew as someone with over a decade of experience.

And sometimes I know things without really knowing why I know those things, and that makes a spectacular challenge in helping educate someone who is eager to learn–to the extent that I sometimes had to relearn things I already know, this time with more intellectual foundation.

Another of my job responsibilities is attempting to make significant improvements to our codebase at a higher level. Not long ago, these two things collided when I decided to try my hand at cleaning up our test suite, which can take upwards of 15 minutes (with parallel pipelines!) to run in CodeShip. That’s a far cry from where we were a few months ago, when our test suite was finishing builds in a speedy 3-5 minutes.

Beyond feature tests, which are meant to be literal end-to-end tests, I noticed that it’s not always obvious to developers when you should stub objects or calls to methods in unit tests. And as I had a discussion with my former mentee, Monique, about it, I realized it’s sometimes not even clear to me what my principles are on the subject sometimes.

What better a way to document your principles than by deconstructing them? Here’s some of my principles, that you might be able to relate to.

Unit tests should adhere to single responsibility patterns

If your class adheres to single responsibility patterns, why wouldn’t your tests for it? This should be a no-brainer.  Pretend you have a service object called SignupUser. Its purpose is mostly clear in its name and it might be obvious to you that it’s going to use instances of other classes in fulfilling its purpose, namely User. This is contrived, but bear with me.

This is such a simple class but you can see that this method is creating a User object and subsequently making calls to a mailer and an event-logging system. As the app evolves, it may grow as well, but generally the things it does are limited to this particular interaction.

Who knows what’s happening in the event logger or mailer? You shouldn’t need an awareness of how other class’s methods work when you’re building a unit test. The unit test should test the behavior of the class being described and so it is fair game to not extend your unit tests to the behaviors of those classes. The methods for those classes should be tested within their own respective unit test class.

Another old favorite is when a controller calls a method on a model and the controller is tested against behavior that took place inside of the model:

This is testing behavior dictated by Item. Simple behavior, yes, but you could just set an expectation that the method was called, which stubs it in the process:

Let’s be clear here, though: This approach to testing walks a really fine line when it comes to ensuring full test coverage. I showed this example to my boyfriend, also a developer, and we almost broke up over it. The police even came out to our apartment to break up the ensuing fisticuffs. I mean not really, but what I’m getting at is this: you may have your own opinions here. And that’s cool. As long as you know why you have that opinion and that you’ve decided that what you write is the best fit for your test! Capisce?

Don’t test the framework you’re using.

Occasionally, I come across unit tests for ActiveRecord models that test against the behavior of Rails and ActiveRecord. This isn’t necessary and it can actually lag your test suite’s runtime because it is guaranteed to produce database transactions.

For example, you shouldn’t need to test for persistence on creation of an ActiveRecord model. If you have a valid model, it’s implicit that it will properly be saved. However, behaviorally, it’s fair game to test your validations.

Bad test:

Good test:

In a similar fashion, it’s also not uncommon to see record persistence being tested within a controller test:


This is completely unnecessary and testing that the controller makes a call to save should suffice:

Don’t Test Against APIs

This came up during a conversation with a friend of mine. He was working on a side project developed in Rails and was a bit green with test-writing and was asking for my opinions on a few things and somehow it came up that he wasn’t mocking requests to an API he was using.

This wasn’t for any “dumb” reason—he just wasn’t sure how you were supposed to account, in your own application, for changes in response objects from third party APIs. And well: you shouldn’t. That’s not on you. But I can understand that that is a hard answer to swallow (the real answer, in my opinion, is that any API that changes so drastically that it breaks your app without bumping version number is a really crappy API and you should consider not using it).

Disable everything by default.

I appreciate gems like Webmock, which allow you to universally prevent all outside requests in your test suite. Not just because they can lead to slow test suites and oh-so-joyous timeout-related failures, but because well, some APIs really suck.

Recently in my job, I was reviewing a pull request for someone and noticed something curious. He had added an initializer which disabled all outbound requests to this API in development or staging environments. I immediately questioned that. “The API doesn’t have a sandbox, just production.” And I grimaced.

But imagine a world where Webmock didn’t exist and someone forgot to stub a request and suddenly there it is: test data in your production environment. Gross. What a nightmare.

Spec helpers can be your friend.

If you’re using Rspec, consider building spec helpers for mocking frequently used API calls.

Mocks and stubs for API calls can be verbose. And, if you’re in a position where you have to upgrade which API version you’re calling, can be a real nuisance to update every place in your test suite where you’ve mocked response objects.

Last year, I had to switch Treehouse’s credit card payment processing library to use a newer version of Braintree’s API. We had quite a number of tests that involved credit card transactions. And what a sigh of relief I breathed when I realized all of these stubbed requests were centrally located in a single spec helper like so:

With this, I can simply call stub_successful_cc_purchase from any test and know I will reliably get that result. If Braintree were to change their API response for their sale transaction endpoint, I could just update this one line of code instead of having to update hundreds of tests.

Don’t stub because you’re feeling lazy

Look, I know how it is. You’ve got a deadlined PR open. And you just did. not. have. time. for. specs. So you throw together some half-assed specs like a house of cards. There’s a difference between stubbing for good reason and stubbing literally everything, including private methods in the same class.

Terrible contrived example:

Your tests should cover your private methods in the same class. Don’t stub those. Doing so is like leaving a time-bomb for the next person that works on the code. Or leaving them to defend themselves from a roving pack of football players or whatever.


Ignore my principles and establish your own through deep introspection and personal experience

The cool thing about being a developer is that for something so logically driven, it’s highly subjective. There’s no one right way to do things. You might hate my principles. And I don’t care. What I do care is that people establish reasons for the things they do and feel comfortable defending those decisions, using their best judgment to write quality code.


30-Minutes-a-Day Development or How Not to Burn Out on Your Projects

One thing that destroys me as a developer on single-person projects is over-enthusiasm. That is, I have an idea, I get very excited about it and the following things happen:

  • I dedicate a night or a weekend to executing on it.
  • In the course of that time, I finish roughly 50-75% of the work on it.
  • The next day or next week comes and I don’t have time to finish it because my schedule is full of other things.
  • I burn out and abandon it.

This all changed when I first decided to start my side business, Creepy Postcards. If it hadn’t, I wouldn’t be calling Creepy Postcards my side business.

Creepy Postcards is a largely offline business. Customers fill out a brief form giving me information about a friend or family member, I exercise my creative writing prowess, we converse a little bit more, and I ultimately mail a postcard through the United States Postal Service.

The last thing I want as a business owner is to waste an inordinate amount of time working on a web application. That’s why I took to single-owner project planning.

As a developer, it’s easy to associate project planning with bureaucracy. It’s something I experience in my day job and although I know it has some value, I still loathe the downtime, the calls, the slow pace, and the feeling of a million sighs passing through me as I think, “I could be using this time to be productive.

It’s especially hard to see the value of it in my side project, but that’s where it’s more valuable. In my one-person business, I don’t have product managers, data scientists, or designers. I need to list out what features I want to add now.

The 30-Minute Task

In order to be quick-moving on a project, I need to break features down into short tasks, tasks that I can resolve in 30 minutes or less. Tasks that keep me actively working on the project, but allow me to walk away from it after that time has passed.

I hate project management tools like Pivotal Tracker. I hate the concept of something relative like “points” driving the meaning of a feature, for a couple of reasons:

  • As one of my coworkers, Ryan Manwiller, pointed out once: 1 point to you does not necessarily mean the same thing as 1 point to another person.
  • There becomes a problem with “inflation” of points where the value of 1 point cannot be broken down any further. You can have 2 tasks, each worth 1 point, and one of those tasks could take 15 minutes while the other could take 3 hours. If someone is dependent or blocked by one of those tasks, “1 point” does not communicate to them when they can expect to become unblocked by your work.
  • When a task hits an unexpected bump, which is fairly typical in development, it is harder to account for that in a point-based system. Say I am refactoring a class and have allotted 3 points to that task, only to discover halfway through my refactoring that there is some gnarly coupling between this class and another class that is going to take a couple of days to resolve. What am I supposed to do there? Do I update my points? And if so, what metric am I basing the point value on now? This gets confusing.

That’s why I think point-based project planning is idiotic. And not just for developers. It lacks a human element to it. It has its heart in the right place, but it just does not work.

Instead, I find value in writing down feature ideas, in language that is readable to any human being, and then breaking that idea down, as I said before, into 30 minute tasks. The tasks do not have to be accessible to a layperson. They do not need to be customer-focused. They can be as technical as I want, as long as they accomplish something.

The value here is that if my assessment is off on one item, I generally have a really strong idea of how skewed my timeline is because each task represents the same amount of time. But, more importantly, I break things down into such atomic pieces, that I generally can foresee issues before I hit them and can plan around that.

Real Example of a Start-to-Finish Project Feature Planned in 30 Minute Blocks

Let’s use a concrete example. Last year, a friend made a really good suggestion to me: Offer people the opportunity to type the content of their own postcards and automate the process more at a discounted price, leaving the possibility for a full custom order.

This sounds like a simple idea but there are a lot of moving parts to it:

  • My ordering system was not advanced enough to build on top of it. It was simply a call to Stripe’s payment processor from a controller with a hardcoded price.
  • Users had no awareness of what cards were in my inventory and because of that, they didn’t have a true sense of how much content could fit on a card.
  • My order form was a pain point in itself. It was cutely designed to fit entirely on top of an image of a postcard. Any additional complexity there would destroy the simplicity of that UX. And I’m not a designer so it’s hard to gauge how to handle that!

To get around this, I needed to do the following:

  • Inventory my entire postcard stock.
  • Implement some sort of management for that in my app using Carrierwave and AWS S3.
  • Refactor my billing “system” into a true library that was capable of processing differently priced orders.
  • Re-envision my order form, possibly being a bit more crafty with how I build orders through calls to action.

Piece-by-piece, these are huge undertakings, so let’s break this down some:

  • Inventory my entire postcard stock:
    • Take front and back photos of each card (about 100 in stock at the moment).
    • Clean up photos on computer.
    • Store photos in S3 bucket.
    • Build a model in my app to represent cards in inventory.
    • Populate my production database with each card.
  • Implement some sort of management for that in my app using Carrierwave and AWS S3.
    • Add Carrierwave and S3 gems to Gemfile.
    • Update my dotenv file and export ENV to Heroku with my S3 credentials (public access key, secret, and bucket name).
    • Update my Carrierwave initializer to use S3.
    • Build a new controller for card inventory items that includes an action for adding new cards.
    • Build out views for uploading and building new cards.
  • Refactor my billing “system” into a true library that was capable of processing differently priced orders.
    • Extract billing logic out of my CardRequestsController and move any Stripe API interaction into its own class in /lib.
    • Evaluate what is part of the card request creation process and establish a service class that will create a billing task and then handle follow-up record processing.
    • Break my CardRequest model up a bit further to store price. In my case, a CardRequest is not unlike an Invoice–it maintains record of the Stripe transaction and is a state machine.
  • Re-envision my order form, possibly being a bit more crafty with how I build orders through calls to action.
    • Establish an “available cards” gallery
    • Add “order this card!” buttons to each gallery item that pre-populate the order form.
    • Make order customizable or specific.

That’s a lot of items, but each one takes about 30 minutes (or less) total. The important part being that I feel confident that I can sit down and completely finish the item in one easy session. This means if I know I have a difficult problem ahead, I can continue to ponder on that some and keep the project fresh in my mind since I am actively contributing to it on a daily basis.

Doing a breakdown here, you can easily catch your trouble spots. If you can not break a task down into small atomic pieces that are not vague, there is a chance you are hitting a paint point in how you understand your work.

In my case, my whole section of “Re-envision my order form” is vague and hazy and doesn’t have truly actionable items. I know these things will take me more than 30 minutes since I don’t have good UX experience. That’s why these things are at the end of my list, so I can mull over them some more and revise my actionable items before I get to them.

Using This Practice for Your Day Job

30-minutes-a-day is the bare minimum. You could apply this practice to your day job too and fill 5 hours of development with 15 unique 30-minute tasks. Given how many distractions most developers face day-to-day from external forces (critical issues, unplanned calls, drop-in discussions with other developers about things you’re not directly involved with), having small atomic tasks works really well since there’s a good chance you will find uninterrupted 30 minute windows of time to do your work. You might feel really good if you knock out about 10 of the things on your list.


In the case of Creepy Postcards, I’m not hard deadlined. After taking my business offline last fall due to an overwhelming number of orders and not having time for order fulfillment, I decided recently to reopen shop for at least the month of June 2016 in response to customer demand (I never thought there would be true demand for something as silly as creepy postcards, but here we are!), so I gave myself an easy deadline of 3 months, which is way more time that I would need to add features I want.

But for you, you might have greater external forces driving your deadlines. Deadlines should be a compromise of what’s needed and what is actually reasonable. When you understand what you’re working on at the smallest unit of time possible, you should have a better understanding, ultimately, of how much time overall you will need to dedicate to your project. If you’re smart, you’ll approach this conservatively and buffer your estimate some to cover the unthinkable (development problems) or the unforeseeable (illness).

If used in a multi-developer project, it’s a must for all developers working to follow the same practice if you expect to understand your time estimate.

If external forces insist that the deadline must come sooner than what you know to be your reasonable timeline, you know at this point that compromise is needed, whether that’s additional resources (other developers) or removing scope from your project to fit within the timeline.


I understand. It sounds too perfect, right? Try it for a day though. Really, just a day. That’s all the time it takes to wrap your head around whether it will work for you. Start the day by breaking your work down into 30-minute tasks. Write those tasks down. And do those things. Even if you think, “that sounds like nothing…”–write it down. At the end of the day, you will have a much better understanding of how much work you have actually accomplished that day.

How to Use Searchkick and ElasticSearch in Your Rails App For Complex Search Indexing

For reasons that elude me, I have always been obsessed with “speedcoding.” That is, I like to see how fast I can implement a very large feature in a ridiculously short amount of time. I won’t lie: this kind of trait goes hand-in-hand with phrases like “cowboy coding” and “Balmer peak,” and with age, I’ve largely outgrown it, but the mood still hits me every now and then.

I recently enjoyed one of these moments while toying around with some code for Treehouse, for the fun of it.


In a past life, I spent about a year working on a team for DeviantArt whose sole purpose was to improve search results on the site. If you were not aware, DeviantArt’s search is done entirely in-house by people who have PhDs in math. They’re brilliant people who will talk your ears off about facets, scoring, histograms, and tagging metadata. I didn’t work on any of the search indexing services myself (which were all written in C++), but I was heavily exposed to the bits of it that were included in the main app, written in PHP. And as a result of that, I know more about search indexing than I’d like to say I know.

CloudSearch or Ransack?

So, seeing poorly implemented search indexing tools also causes me mental anguish. That’s how I feel about Amazon CloudSearch, in general, which is a tool Treehouse has used for one of its most major site features. It’s not the worst indexing tool in the world but I really dislike that you have to hit your indices through an API since it’s all hosted externally, which seems unnecessary, unlike hitting a CDN for assets. That’s like hosting your Redis stores on a third-party service: why. But, worse, for a few internal tools, Treehouse uses a Rails gem called Ransack.

I don’t mind Ransack. It has its heart in the right place, but it leverages ActiveRecord for its querying and so, you’ll have to put a lot of effort into optimizing indices on your database tables if you expect it to work even halfway decently as the size of the table you’re querying grows. This also assumes you’re not doing expensive table joins as part of your query.

Searchkick to the Rescue

I recently decided to see what would happen if I used ElasticSearch for a fairly complex search, using a gem called Searchkick. I really like Searchkick because out-of-the-box, there’s no configuration needed. If you want to index your User model, it’s as simple as adding the gem to your Gemfile and a searchkick directive to the class:

And then reindexing the model:

The cool thing here is that you can also do your reindexing asynchronously so that it won’t block processes or have a dramatic impact on your application’s performance.

You can then search all attributes of User (i.e. name, e-mail, city) like so:

And you’ll find plenty of demos and tutorials for that all over the place, but who ever needs the simplest use case?

I had a few different needs:

1. Because Searchkick uses ElasticSearch, you can’t chain scopes off of the model prior to running the search like so:

I mean, you can, but — it’ll ignore the named scope and still run your search against all User records. So I needed to be able to account for different scopes, and the above piece of code simply does not work and cannot be made to work.

2. I needed to be able to sort my results by a variety of things which weren’t necessarily attributes on the model itself. For example: I needed to sort by the time difference between the model’s created_at attribute and its updated_at attribute. Or I needed to sort by the created_at timestamp on a child association. ElasticSearch’s DSL supports a sort order constraint, but how do you sort by a value that isn’t indexed with the model?

3. As I started to index more things, I noticed my controller logic was growing wily. I needed some sort of presenter type class or simply a PORO to organize my Searchkick search.

So I’m going to walk through how I developed this search feature, stopping to explain my thought process along the way. Because I didn’t feel like getting sued by my employer for any potential intellectual property theft, I’ve used a completely different search feature that has absolutely nothing to do with what I was originally building a search for.

Once I was finished writing this code, I was able to roll out a second sortable, filterable, search tool for another model in about 20 minutes reusing the same pattern.

Where I Started

I wanted to index a model called Movie. Each Movie is directed by a Director and has many Actors through a relational model called ActorRole.

Searchkick allows you to override which columns are used in searches via a method called search_data. My first step is to find out what things I need to index here!

What this does is allow me to continue indexing the attributes on the model itself, but also includes a couple of other pieces of denormalized data from associations, namely the name of the Director who directed the Movie and the names of anyone who acted in the movie, both pieces of data that are not stored on the Movie record.

So, assuming that I have a Movie with the title “The Room” directed by esteemed actor, director, and writer Tommy Wiseau, I can now search for “Tommy Wiseau” and “The Room” will be one of my search results–both because he acted in the movie and directed it.

If you’re used to working with relational databases, seeing denormalized data stored this way might bother you, but it shouldn’t. Remember, the purpose of these indices is for aiding in searching, not for data management. Your indices do not need to look pretty–they need to simply be a collection of values that you search with, mapped to their respective data types. That’s why it’s a separate data store from your primary database, afterall.

You should always reindex after making changes to the search attributes, so that ElasticSearch can pick up anything new.

Implementing This In A Controller

As you can see, the search method, provided by Searchkick, takes 2 parameters. The first is a query string. The second is an options hash. Already, I’m passing two options to set up pagination support. You might imagine how hairy this will start to get once I need to do more complex search functionality.

I’d like to move this logic into its own service object for a couple of reasons:

1. I’m a big fan of keeping controller actions skinny (as most Sandi Metz fans are)
2. If I later decide to add additional searches, I am likely going to reuse this logic.

So let’s do that.

I still don’t like this though. It’s not generic enough, and we’ll see why in a minute as we continue to build it out. I prefer to get something working before trying to refactor it.

Extra Beef – Filtering

I don’t know about you, but I’ve never been to a movie site that didn’t offer browsing by genre. That’s just an obvious thing about movies, yeah? So we need to work that into our search somehow. The problem is, since we’re using ElasticSearch, we can’t do any initial filtering through ActiveRecord scoping. Everything needs to take place within the Searchkick options. So we need to consider that in our search class.

The options hash is now starting to get polluted and messy, which means it’s probably time to extract parts of it out into its own method:

These are simple use cases. But what if you wanted to filter on something a bit less obvious that doesn’t necessarily seem like it would be a search keyword–like say, filtering Movie based on whether the director is still alive or has died before a certain date. Sure, that’s not a common thing to filter on, but a majority of our lives as developers are building out logic that has some special meaning to our product or customer, otherwise we’d all be using pre-existing open source software and calling it a day.

To do this, I need to add that denormalized data to the search index.

When you reindex your model, Searchkick will pick up that you’re indexing a date and you’ll be able to evaluate it as such in your search:

lte and gte are both parts of the ElasticSearch DSL, if you were curious. And honestly, I think it’d be weird if someone had a future death date listed but, again, we’re just toying with data here 😉 You could even filter within a range if you had two date objects, using both lte and gte.

I could continue adding ways to filter on additional attributes, but it’s largely rinse and repeat from here, with some mild Ruby refactoring along the way.


This was the one part that gave me pause, but it’s not wildly different from filtering via where. Say I present Movie results in a table that contains columns for its title, genre, release year, and director’s birth year. The first three items are simple to sort on because they’re already indexed attributes. Just like we had to add the director’s death date for filtering on that, we’ll need to add the director’s birth year in order to provide sorting options for that:

And add a sorting option to our search call:

Pretty simple. One thing I want to point out here is that ElasticSearch allows you to sort by _score. You can sort by multiple attributes, so you might want to consider continuing to sort by score, because that’s one of the niftier things about Elasticsearch–as it receives more queries and its indices grow, it grows more intelligent about which results are relevant, and sorting by score will weight the more relevant results towards the top.

Moving on! Now, our MovieSearch class, in full, looks like this:


And this is where we can start to think about refactoring potential. Some of the logic in this class is tightly coupled to the Movie class, but some of it is generic enough that it could be used for any model using Searchkick for searching. So maybe it’s time that we break this into a base class which our MovieSearch class can inherit from:

I added a new method called search_class that raises a “Not Implemented” error on the base class. If the child class fails to implement that, as it should since it specifies which model to search, that error will be raised. Because we were able to extract so much into the base class, the MovieSearch only had to include the search_class method and a where method for movie-specific filtering logic. You could potentially override the order method as well if you wanted to have a default sort order, like say, if you were filtering by the director’s death date, you always wanted to make sure you sorted results by that attribute in descending order.

Final Thoughts


There’s a lot more you could do here. I just wanted to dig in a little bit beneath the surface of all the tutorials that choose to cover the most basic use case. One thing, I’d like to point out though is that when you use ElasticSearch on a model that has child associations in its search data, you’ll need to make sure that the parent model gets reindexed when the child object gets altered. Searchkick automatically reindexes when the model itself changes, so just as you would handle cache-busting, you need to make sure your associations have a touch: true directive to trigger this reindexing!

One of my coworkers, Amos, also shared with me an interesting, alternative approach to handling these kinds of issues by adding instrumentation to the child model’s lifecycle that notifies when it needs to be reindexed and then subscribing to those notifications to ensure that a reindex takes place. I really like this approach too and would heavily advocate it if your searches start to get heavily burdened by ActiveRecord associations.

“I hate service objects and think aspect-oriented programming is the way of the future!”

That’s fine and I understand there’s a couple of different ways you could propose to architect the code I wrote here. Instead of building a service object, you could make a Searchable aspects module that is included in your model and override the where and order methods within your model instead of building separate search classes. On one hand, I’m not a gigantic fan of this because it places logic that doesn’t belong on the model in the model. On the other hand, if you look at how Searchkick works, it’s already doing this by forcing you to override its search_data method on the model. In short: ¯\_(ツ)_/¯

Code Climate and Flog

True story: Flog will hate you if you have even the slightest bit of complexity in your search_data methods and if you choose to extract out relational data into their own methods in cases where you were needing to pass blocks to map, you’ll start to get that stinky feeling that you’re violating the Law of Demeter. So, in a way, I feel like having search_data on the model is a code smell that Searchkick forces you to commit, but, to reiterate: ¯\_(ツ)_/¯

“I love you for writing this but I know something you don’t know and want to contribute!” /
“I love you for writing this but I’m a hands-on learner and want to download the code to play with myself!”

Did you find this article useful but want to have a more hands-on learning experience? Good news! I’ve put this code on Github where you can clone it and play with it on your own.

1Q84 – Books 1 and 2

I’m currently 700 pages into the 1159-page Haruki Murakami novel 1Q84. Here are the thoughts I’ve collected, spoilers and all, in no particular order thus far.

There be spoilers below. 

  • What if the novel that Tengo is working on after Air Chrysalis is actually the novel I am reading, 1Q84? What if Aomame has been written into the novel? After all, the foundation of the book is based on 1984, where history is rewritten. Perhaps Tengo is in a future where the past is forgotten and he is rewriting history, reminiscing of a childhood love he never saw again.
  • I really appreciate that Tengo has forgotten his girlfriend’s name. I feel like so much of life is repetitive events with people we know without really knowing. And it’s not that you don’t care about these people, but just that in going through the motions, you forget to get to know them further.
  • I don’t know if it’s just me but I had no idea what the Willow House was supposed to be for the first two chapters of Aomame’s story that mentioned it.
  • I can’t not picture the Dowager as an American southern aristocrat with Cruella Deville hair.
  • In that same respect, I also can’t not picture The Professor as a Japanese version of Edward James Olmos. I have no idea why.
  • They keep quoting lyrics from Frank Sinatra’s “It’s Only a Paper Moon.” Given the two moons in the story, what does it mean? In the song, love isn’t real without that other person–it’s a fairytale. Is 1Q84 a fairytale as well until Aomame or Tengo remember they’re in love and then suddenly become a part of it?
  • Janacek’s Sinfonietta is such an odd choice of a song to have recur throughout a book. The intro fanfare is so cacophonous and discordant. It’s a war theme.
  • There’s a lot to make me think a primary theme of this novel is feminism. So much sexual abuse and vengeance in the name of sexual abuse. Aomame doesn’t want a lover. Ayumi doesn’t have time for a lover.
  • Speaking of which, Aomame’s revenge on her dead best friend’s husband? I can’t think of anything more annoying than literally having to replace every. single. item in my house. That is some skilled shit.
  • I love the way Murakami describes the first appearance of Ushikawa:
    • “…some creepy thing that had crawled out of a hole in the earth — a slimy thing of uncertain shape that in fact was not supposed to come out in to the light.”
    • “…black, curly hair that had been allowed to grow too long, hanging down shaggily over the man’s ears. Ninety-eight people out of a hundred would probably be reminded by it of pubic hair. Tengo had no idea what the other two would think.”
    • “It was not just that he had terrible style: he also gave the impression that he was deliberately desecrating the very idea of wearing clothes.”
  • Tengo’s girlfriend’s dream about the cottage in the woods really freaks me out. She says she has a sense of dread about why the food was left at the table, why after hours, it’s still steaming hot, why it’s getting dark and whoever left it is still not back, as if they abandoned it to run away from a monster. And Tengo suggests that she is the monster and she gets offended. But what really freaks me out about that is just the continuity of the scene. All alone with the forever-steaming food. Isn’t that what hell is? Being stuck forever with dread?
  • Book 2 is really boring and drawn out. I feel like he was trying to be really dramatic in spending 8 pages describing a handgun and how it’s handled, but the deep impact of that really falls short. Yes, guns are kind of more heavy than they look. Yes, they’re made of metal. Yes, they’re powerful and you have to be extremely safe with them. I get it. I did appreciate the Chekhov reference that once a gun appears in a story, it has to be used. I feel like, at this point, I don’t really care if the gun gets used or not, though. Murakami makes it really hard to care about Aomame given that she’s not a very emotional person.
  • I have really appreciated how blunt Aomame is though about her sexuality, from her telling a guy in a bar that she likes big cocks down to her weird sensation the morning after of her asshole having been stretched open from anal sex. It’s a little bit shocking, from someone who presents herself so properly in all other venues of her life.
  • The Little People make me think of The Lilliputians in Gulliver’s Travels. I can’t really figure out what their angle is though. I know they’re not good, but I don’t know that they’re bad either. They’re just… chaotic supernatural forces, as far as I can tell, that are tied to events that do seem bad–child molestation, disappearances, cults, exploding dogs?
  • Fuka Eri asking what Tengo what “real” meant was interesting given her character’s whole existential crisis in Air Chrysalis upon learning she had this dohta clone.
  • Murakami is obsessed with breasts. I know more about Fuka Eri’s breasts than her face.
  • I don’t know what to feel about the whole concept of the maza and the dohta. Is Fuka Eri being separated from her dohta (the shadow of her heart and mind) the reason she is perceived as dyslexic or is she actually dyslexic anyway?
  • What are the criteria for being chosen as the Perceiver and Receiver? Is it just a coincidence that the Leader and his daughter (or her dohta?) are both? What happens if the Perceiver and Receiver don’t know one another? Do the Little People have to orchestrate that whole shebang? Are they a global force or just a Japanese thing?
  • I feel like there is a bigger conspiracy laying ahead. The first time that Tengo got a call from Fuka Eri when she was in hiding, he could hear children in the background. I feel like she was staying in the same condo that Aomame is staying in after killing the Leader. Which I think means that two opposing forces are actually working together (possibly the Dowager knows the Professor? Or… the Dowager’s long lost son is the Leader) Who knows.
  • I really hope this book wraps up in a way that doesn’t just feel like the whole thing was a homage to Orwell’s 1984, because I’d be really disappointed with that. I just think Murakami can rise to the occasion to not need to use another literary work as a plot crutch, especially for his longest work yet.

You Can’t Live On In Anger / 7 Months After Miscarrying

31 weeks ago, on Father’s Day 2015, I rode my bike to CVS. For two weeks, I’d had a really obnoxious cramp in my lower abdomen. I thought I had an ovarian cyst because it was sharp and stabby. But the doctor didn’t find anything wrong and sent me home.

I made the trip to CVS every couple of weeks usually, to purchase a home pregnancy test. It was just a formality for me, to the point that when I took the test, I typically just set it aside and would glance at it later in confirmation that things were normal. Normal for me, anyway.

But this time, before I could even fully lift the test back up, something was off. It was positive. Extremely positive. And like most people with an unplanned pregnancy, I started to pace around frantically, trying to catch my breath, before calling my boyfriend. Then I took another test. And another. A real Hollywood cliche, but it’s grounded in so much reality.

We walked around the neighborhood like zombies for an hour. It felt like a nightmare. Not because I hate children or because I don’t love Joel. My brain just couldn’t comprehend the amount of responsibility.

The baby changed things. It changed me. It changed my relationship. And it grew. And as it grew, I grew inside. I bonded with it. I ate a lot of kale suddenly. I sang songs like “Hey Jude” to it even though I know fetuses that small can’t hear. Some days, I felt like a whole bright world awaited me. Other days, it felt like it was just me and baby versus the world.

Then I found out that one baby was actually two. And I felt disconnected again. I felt ashamed for feeling disconnected. It’s hard feeling like you spent time bonding with one person only to find out that all along, you were actually bonding with two people. It felt weird knowing there was another member audience to my singing. It felt weird knowing the different foods I craved… that maybe each one was triggered by a different baby.

And when the doctor said the words, “high risk,” it terrified me. Then came abdominal pain I’ve never felt before. Pain I’m sure is not even half as bad as labor pain, that caused me to double over, lose my breath, and not be able to stand. And the babies were gone.

I had to take a week off of my job to recover from the loss. I didn’t know back then what all that sedentary navel-gazing would do to me. Like the twins changed me, their loss changed me. And my reaction to the loss was nothing like my boyfriend’s reaction to the loss. And that changed the dynamic between us as well. Seeing happy families made me cry. Hearing people complain about their young children annoyed me because I felt like they had lost sight of what they had. I felt lost.

And worse, I felt no finality. When you are pregnant, you get a due date. My original due date was February 23, 2016. Because they were twins, the due date was actually more like around 36 weeks, since twins are typically born premature, so January 23, 2016. But twins vary greatly in when they decide to come. Anywhere from 32 weeks to a normal full-term. It was impossible to have the feeling of “this is when they’d have been born. I can let go.”

Shortly after I found out I was pregnant, I began a cross-stitch piece, not knowing how epic it would be, of the Overworld map of World 1 in Super Mario Brothers 3. After the loss, I continued. Somewhere around November, I knew, even though I was nowhere near finished with it, that whenever I finished this map is when they would have been born. It was a pregnancy-length piece.

And sure enough, I finished it on January 24, 2016, 1 day past 36 weeks. And not that the piece dictated where my grief ended, but I looked up from the piece and realized I’m in a better place now than I was before.

For months, I was angry. I thought my grief would be channeled through sadness. Instead it came through in anger. I was angry at everything in my life. I was angry with Joel. I was angry with where I was living. I was angry with my job. I was angry with myself. Nothing could make me happy because I wasn’t even willing to give it the chance to do so. I was defensively preventing myself from moving forward with my life.

And then, through some magic grace in the universe, a calm surged up and embraced me. And I was able to breathe again. I still get angry. But I’m a little less so now.

And strangely, the map from start to finish… it works. There were a lot of hills. And hammer brothers. And invincibility stars. And mushrooms. And Koopas. And magic flutes. And three lives at the very start. And I lost a couple along the way, but I somehow made it to the end of World 1.


“Woman in a Meeting” Speak And Its Role In Software Development

Last week, I came across an article on Buzzfeed, a news source that I don’t really count as a news source, on the subject of “Woman in a Meeting” speak. It was all about the idea of women sugar-coating their opinions in business settings out of concern that they will come across as brash or bitchy. That article, of course, stemmed from a Washington Post article in which famous historical quotes were re-imagined as if they were spoken by women in business meetings.

The topic hit very close to home for me. Not because I am guilty of it–in fact, if I look through my most recent exchanges with others, I am fairly strong-willed and blunt in how I share my opinions with others. I occasionally use emojis. I occasionally say “haha” when it’s appropriate because I like for people to know I’m not a robot.

However, I stand by the points I make generally and don’t make excuses for them.  Why? Because a fairly large part of my job is providing critical feedback to others. I simply can’t afford to hem and haw on my opinions, because people rely on me to know what I’m talking about. This isn’t me being arrogant. Being cutesy about it would only give others pause about my ability to provide assistance, so it has no place in my exchanges with others.

But I didn’t always speak bluntly. It’s a strength I passively developed as I grew as a software developer and I think it’s really important that you develop good communication habits early in your career that allow you to continue building that voice! Occasionally, I see this speech pattern in others and it has little to do with gender identity. Examining it as such is using it as a crutch, I think.  Having an opinion and being able to state it so it’s heard is like singing. It doesn’t matter how eloquent or beautiful it is if no one can hear it. Having a voice is about having strength but also balancing that strength so that there’s still melody and you don’t sound like you’re yelling. So here are some thoughts on building that trait.

Don’t Apologize for Your Weakness

“I’m sorry” has one place in your interactions with your peers and that’s in expressing sincere remorse.

Times it is okay to say “I’m sorry” as a software developer:

  • You force pushed commits to master.
  • It’s been 2 days and you forgot to review someone’s code.
  • You insulted someone. Or their family. Or their beliefs. Or something deeply personal.
  • You have severely inconvenienced someone (in a way that is obvious to you)
  • You overcommitted yourself and failed to hold to your commitments in a way that caused problems for someone else’s workflow.

Here’s times you shouldn’t apologize:

  • You don’t know something
  • You don’t feel confident about your opinions.
  • You have an opinion that conflicts with someone else’s opinion.

Also, don’t confuse apologies with gratitude. Suppose someone took time out of their day to explain how something works to you. Don’t say, “I’m sorry for eating up your time.” Say, “Thank you for taking the time to explain this to me. It’s going to be useful when [whatever it’s going to be useful for in the future]!”

Remember, when you apologize unnecessarily, you are diluting the meaning of sincere apologies and you are only adding filler and fluff to a meaningful conversation.

Find Your Strengths

Your soft skills as a developer are just as valuable as your hard skills. These are skills you’ve been working on since you were a child. They are part of your personality. Just like you walked into your 2nd grade classroom not knowing the difference between sedimentary and igneous rocks, you’ll walk into your first job as a software developer with not a lot of knowledge to show off that you’ll soon learn. People’s willingness to engage with you when you know nothing will be built entirely on the kind of personality you have.

Don’t Acknowledge Your Weaknesses to Deflect Your Strengths

Things you might be tempted to say:

  • “You probably know more about this than me”
  • “I’m not an expert”
  • “I’m probably wrong but…”
  • “Just a thought.”
  • “This is just my opinion but…”
  • “I don’t know if this will make sense but…”

These are implicitly understood things. You might say them because you’re afraid if you are wrong, that you’ll look dumb. But they’re not necessary. Regardless of whether you’re an actual expert or not, the person you’re speaking with now has your opinion to decide whether they agree with it or not. And they know it’s your opinion. Or your thought. And really, it doesn’t matter who knows more about what. Because sometimes someone who has expert knowledge of something has a moment of stupidity just like someone who might know very little about the intricacies of a system might have a genius observation.

You Can Express Your Uncertainty Without Putting Yourself (or Others) Down

Here are some great ways to make it clear to your colleagues that you have an opinion, think it might have some worth, but need some additional feedback or assistance:

  • “I’d be interested to hear your thoughts too on this!”
  • “Let’s chat about how we can actually implement this idea I have.”
  • “Can you be a rubber duck and listen to some ideas I have?”
  • “I know you know a lot about this thing I’m working on so I’d really appreciate your feedback!”
  • “I like your ideas but I have some thoughts too that I think would work well here.”

The list of possible ways to express this goes on and can be amended to whatever context is necessary. The idea here is that if you want to establish your voice, stand by your opinions and show others that you are grateful for their opinions too.

You Can “Haha” and Emoji and Cat GIF it Up All You Want

I don’t know why people think these things take away credibility. The people I work with that I like the most know when it’s appropriate to laugh, know that not everything is a personal attack, and have fun doing what they do. The best way to reflect your credibility is by showing others that you like your career and that you feel in your own skin doing it. Don’t stop laughing. Because laughter is part of your voice too just as much as your words are.


You’re Bad At Reviewing Code (Or Are You?)

Last month, I wrote a piece discussing the characteristics of poorly written and well written pull requests. And with that, I started to ponder the other side of the fence: How does one review code well?

Reviewing code can be frustrating, even when the pull request is well-written. Say you’ve been working on the same thing for 3 days now and suddenly you’re asked to review a pull request with a 35-file changeset which includes database migrations and makes significant architectural changes to the application. Big changeset or not, many PRs are very capable of taking down a site on deploy and it’s scary to find yourself responsible for that if you miss something.

You don’t want to take the site down

I’ve done that. If you’ve spent any time working as a professional developer, you probably have too. One time, shortly after I had joined Treehouse, I spent a day or two writing some new stats collection methods that were run as part of a daily rake task. The pull request was approved, my tests passed, the  build passed in our continuous integration service. And then I deployed it. And it took down Treehouse immediately. The culprit? Bad data.

Taking a site down means doing a post-mortem and trying to figure out, “What can we do to make sure this doesn’t happen again?” And that’s great. But it’d be greater if you didn’t land there in the first place.


Ask questions, even if you suspect they sound dumb

One thing that I heavily advocate in reviewing a pull request is letting go of your assumptions about how things work and approaching the code as if you had no awareness of the application’s nuances. As you come across these nuances, first run an internal monologue and explain to yourself how those things work. If you can’t find a way to explain it to yourself in clear, easy to understand language, it’s fair game for leaving a comment on the merit that other developers who aren’t as experienced with the application won’t intuitively understand it.

This might sound like it’s time-consuming, but once you’ve adapted this philosophy for a brief time, it’ll become quick to you, much like speaking a foreign language is with practice.


But don’t be afraid to approve.

You don’t have to be a pedantic asshole while reviewing code. I know, you have this voice in your subconscious that worries, “Will they even believe I reviewed their code if I just give it the old thumbs up without any additional comments?” Sometimes someone will really just knock it out of the park, though. It happens. You don’t have to be pedantic for the sake of fostering credibility. I swear.


“It’ll only be like this for a little while… I promise…”

I’m guilty of this occasionally. It happens a lot when you work on large, moving-target type projects. There’s a compromise between understanding deadlines and understanding that you’re introducing future technical debt to an application. If you work on public-facing products, this can happen a lot.

When you see something in a pull request that looks sketchy, hackish, or like a shortcut, and the author of the code is excusing it with time constraints due to a deadline, it’s appropriate to question the timeline for remedying the workaround or at least prompting a discussion of: what the long-term plan for that workaround is, and making sure that it is documented somewhere so that it doesn’t get left behind as painful legacy code to clean up for some new developer 3 years down the road. If you ever see #TODO: Fix this in a pull request, a discussion should be happening surrounding that.

Mind you, this conversation should not be done in a finger-pointing manner. It should be done constructively, with the primary concern being the health of the codebase you’re maintaining. But also empathetically, with the understanding that one day, you too will be on the opposite side of the table.


Share knowledge if you have it

Reviewing a pull request is not just a matter of “does this work?” It’s a matter of “does this work in the most effective and efficient way?” If you know of a way to more cleanly write something and you fail to point it out to the author, you’re doing a disservice to them, intellectually, and future code that they write. This happens a lot when working with Rails apps, because there are so many useful things available through ActiveSupport that even the most seasoned developers might not know about.


It works, but does it work well?

Just because you tested something in your local development environment and confirmed that it works doesn’t necessarily mean it’s good to ship into a production environment. Performance should be a concern as well. Can you benchmark changes made? Do you have access to New Relic or other tools locally? If you suspect that there may be potential performance issues with a pull request, you should be checking these things.


Does it scale?

What works now may not work well forever or even next month. Don’t think of the pull request in isolation. Think about how it will gel and coalesce with other parts of your codebase. If you have 500 users today, how do you think this code will fare when you have 5,000 or 50,000? Are there logical constraints to the code being committed that will make working in future product features difficult or annoyingly complex?  Does this addition to your codebase put it one step closer to being a monolithic piece of crap? Would it serve you better as a micro service?

Having these conversations sooner than later will save you headaches in the future. You don’t have to over-engineer. But you do have to at least consider the implications of not over-engineering.


Is there something else that will do this better?

This is awkward. Someone has just written a large pull request but you know of a very simple gem or library that does exactly what they just labored over, only the gem/library you know of does it… better or more thoroughly.  Do you say something? You should. You should also leave that decision in their hands of what they want to do with that information, awkward as it is.


Remember, your coworkers are humans too.

When I review a large pull request, I compliment just as much as a I critique. Even if it’s just a “thank you for doing this.” People need positive feedback. They need to be reminded every now and then that there’s a reason they’re doing what they’re doing. As cold and robotic as code can be, it’s on us as developers to high five and shower each other with animated GIFs and creepy smiling cat face emojis.

Remember, one day, you’ll be having the worst day in the world and someone will comment on a line of your PR with, “woah that’s an awesome idea, :clap:” and you’ll swell with pride and happiness. Remember that every time you say something nice, someone else might be living that same moment.


Your Pull Request Sucks (or does it?)

One of the things that slows me down the most as a developer is getting roadblocked on a pull request. I can spend a frivolous amount of time, say 15 minutes, actually producing and testing my changes and then on rare occasion be stuck waiting hours or days for it to be reviewed.

There’s only so much you can do to alter another person’s availability to review your code, but what hit me over time is that other developers are like me: they switch contexts just as much as they switch git branches. People need context! Unfortunately, reading a diff is not a fantastic way to establish context and can take just as much time as it takes to review the PR itself. And not having context can cause people to procrastinate or simply forget to review your pull request until you bug them to do so.

I  have alway written pull requests like any other developer might. I explained what the changes were, relative to nothing else. The title of the pull request would be well-written and explain the ultimate goal of the changes made and because of that, I assumed that the changes would be implicitly understood by the reviewer.

Alas, other developers do not necessarily work on the same area of the application as I do. Or have not recently worked on it. Or may misunderstand the human factor of what the changes are trying to achieve.  As someone who has been looking at the code for maybe days, I want to say, “That’s so obvious, do I really need to explain it?”

The answer to that is: “Maybe not, but what does it hurt to do so?” Who knows, maybe in 2 weeks, you’ll need to revisit this pull request. Maybe in 2 months a bug will be discovered that is the result of your changes and other people will get involved. Either way, there is no harm in transparency.

I’ll use examples of pull requests I have done to break down some ideas on what makes for bad, okay, and good pull requests. I feel no shame in this because I’ve learned from it! I work with several people who have produced awesome pull requests that were constructed in ways I found impressive, but putting other people’s work on display is weird and not cool, so this is sticking strictly to stuff I’ve done to highlight things.

What a Crappy Pull Request Looks Like

This is a pull request I did within my first month of working for Treehouse:

Screen Shot 2015-09-24 at 2.29.28 PM

Here’s why it sucks:

  1. What is “the right thing”?
  2. There’s mention of BugSnag, but no link to the actual error in BugSnag.
  3. “Make bugsnag stop crying” is very, very colloquial language. This is more of a nitpick on myself than anything, but if another developer were to look at this and speak English as a second language or not speak the same dialect of English as me, they might be ever-so-slightly confused by that description.
  4. No explanation of what I changed.
  5. Or why I changed it (other than to stop an error from occurring)

This pull request was almost certainly an emergency hotfix. In fact, I’m pretty sure it was me hotfixing someone else‘s code. Which, for all practical purposes, is the ideal situation for writing a very well-formed pull request (and tagging the responsible party!). It was a one-line change that adds a presence check to a variable. But a year and a half later, I don’t have any context for what this change was related to, which previous commit caused the issue I was fixing, or if there was even a GitHb issue logged for it. The pull request was reviewed and merged and probably was okay, but the title and description for it are horrid!

Reviewing a pull request should not make someone feel like they are solving a dramatic mystery.


What an OK Pull Request Looks Like

Screen Shot 2015-09-24 at 2.37.33 PM

Here’s why it’s okay (but not necessarily good):

  • It references an issue (which is not always going to be available if you are building a feature or handling tech debt, but in this case, it’s applicable)
  • It humanely explains how a model works prior to the changes to give the reviewer a comparative understanding of what changes they are about to review. After all, not every developer intimately knows all the logical constraints of every class in the application they work on.
  • It explains why there is a problem with that model’s behavior both in terms of application logic and actual use case.
  • It proposes a solution in response to the problem explained.
  • It explains additional requirements related to the pull request (needing to run a job to fix data)
  • It acknowledges room for future improvements that might be outside of the scope of the pull request, in case those do come up in the discussion.

Here’s why it’s not good:

  • It doesn’t provide information on how it should be tested.
  • It doesn’t cover any concerns or additional implications that might be related to the changeset (in this pull request, I don’t really think there were any, but I think with a larger pull request that touches more classes, this might be a problem).
  • The language used in the title is okay, but it’s not completely clear. “point award” is referencing a model called “PointAward” and yet “vote” is actually referencing a model called “ForumVote.” For anyone that regularly looks at this code, they will likely immediately know what I’m talking about, but if someone new to the application were to look at this pull request, they might not know what a “point award” is (or if it’s a model even) or maybe they will go looking for a model called Vote and be absolutely confused when they don’t see anything named that.

A pull request should direct people to the appropriate parts of the application that are touched without confusion or having to ask for more information.


What a Good Pull Request Looks Like

This is where things start to get more subjective. I’m using an example of a very large pull request I worked on a few months ago for this, in which I was maybe overly cautious about, but I think some the ideas surrounding it can be applicable to smaller pull requests as well. Is this pull request the best pull request in the history of the world? No, of course not. In fact, a few small-ish bugs emerged from it despite having a fair amount of clarity. The point is that it minimizes confusion about the intent of the pull request.

Screen Shot 2015-09-24 at 2.54.49 PMScreen Shot 2015-09-24 at 2.57.01 PMScreen Shot 2015-09-24 at 2.57.29 PM

Here’s why it’s good:

  • Its title expresses an objective and explains what mechanisms will be used to achieve it without being overly technical.
  • The description is well-formatted using Markdown so that it is readable to the reviewer. Obvious? Yeah, but when you’re conveying a lot of information, what looks reasonably readable to you can so easily look like a wall of text to an outsider.
  • It explains what the benefits of the changes are in a way that makes sense both from a technical and business perspective.
  • It breaks the changes down into a changelog.
  • It explains/defines jargon that may or may not be familiar to the reviewer.
  • It raises concerns in a way that prompts for feedback rather than dictating the direction the conversation contained within the pull request will go.
  • It appropriately tags people whose work is greatly affected by these changes or who may want to weigh in on the conversation.
  • It addresses issues that are possibly not within the scope of the pull request but have been observed while working on related library code.
  • It comprehensively covers all known [edge] cases for testing the changes.

Ways it could be better:

  • There is a lot of acronym usage in the description of the pull request. Sometimes that’s okay when it’s a concept that is more commonly communicated as an acronym than not (API) but turning something into an acronym that is not normally communicated that way out of laziness is potentially confusing (e.g. Active Merchant as “AM”).
  • Doesn’t really dig too deep into what underlying problem is being solved (“fraud” is mentioned, but certainly could have exposed more about how that was occurring historically)
  • Although it explains potential test cases, it doesn’t explain how to test those. Testing billing changes in a non-production environment is not always obvious to everyone because a payment processor’s development sandbox is behaviorally different and typically has its own test credit card numbers that you can use for producing successful transactions and declined transactions.
  • It could have explained the technicalities of the code being changed better, but in my case, this was intentional because I knew the person reviewing it was very, very familiar with the code changed.

One other thing that I like to do inside of pull requests is to spearhead conversations by making my own inline notes on code before the reviewer has the chance to do so, pointing out any areas that I am uncertain about that I am looking for suggestions on, adding additional clarity on why a particular line was changed if I think there may be even the slightest bit of confusion. That way the conversation in the pull request is bi-directional.

I like to think of writing pull requests like hosting an out-of-town guest. We have things in common, we speak the same language, we both have the same understanding of how human life works (we both know to breathe air and walk and other human things), but they don’t know all the intricacies of my town even if it might encompass some of the same things they’re familiar with from their own town or travels elsewhere. I talk like I assume they know some things but I’m not going to just jump in and say, “How about that Timbers game last week?” because I know they’ll have no idea of what I’m talking about–they are foreign to my town and they are potentially foreign to this code as well!

It’s common as a developer to think about learning from other developers from a strictly technical perspective: “Bob has more experience with this system than I do and can share information with me about it” or “Lisa is really good with CoffeeScript and might know of something that works better here…” but on a daily basis, every time you are interacting with other developers, you are subconsciously learning something about communication by trial and error. Any time you walk into a dead end with someone through miscommunication or find that something is useful to another person, that’s noteworthy and should impact how you verbalize things in the future! Don’t make people’s brains explode.


I’d love to hear other developers’ thoughts, stories, and musings on how they set up pull requests and ways they’ve found room for improvement. Do you hate my principles? Do you love them? Do you have your own different standards? Comment below.


Disabling Superhero Mode at Night (or: How to Properly Turn off Work Notifications after Work)

Many developers suffer from Imposter Syndrome. I wrote an article about it. In fact, writing about Imposter Syndrome is, like, really trendy right now.

One of the common outcomes of Imposter Syndrome, however, which often goes undocumented, is the concept of “Superhero Mode.” This is a blanket term that I just made up to describe when a developer, often afflicted by Imposter Syndrome, over-exerts his or herself as a way of proving self-worth to others. Superhero Mode is kind of a misnomer because it implies arrogance, but the people suffering from it are often anything but arrogant–they’re often very humble, quiet, and soft-spoken.

And it’s not completely confined to people who suffer from IS, but the two often go hand in hand. A developer feels that if they work extra hard, harder than they’re used to, they will stand out and not be seen as a novice to a system that they are maybe fairly new to. It is sacrificing energy from one area of your life to create a gigantic pool of stamina to burn through on work-related tasks. This behavior starts early and becomes habit-forming, meaning that as you make adjustments in your career, you’ll continue down this road until you painfully burn out.

Unfortunately, the older that you get and the more responsibility you take on (both professional and personal), the sooner you will realize that Superhero Mode is not a scalable solution to professional credibility. First of all, you will become tired by it. Secondly, it will become part of your identity and an expectation others have of you, rather than a pleasant surprise when you exceed normal expectations. This isn’t anyone else’s fault. It is the most important thing you do for yourself: setting a standard of what you’re capable of doing and standing behind it. Maybe this will change as you grow wiser and more experienced, but whatever the case, it is something you have to create an answer for.

That said, if all employees are an instance of the Employee class, then Superhero Mode must be a privately scoped method on that class, never publicly accessible. And by that, I mean it has to be something you turn on yourself, not something others should be allowed to enable on you.

When Superhero Mode Beats The Crap Out of You

I recently spread myself too thin. I was getting angry a lot, but I didn’t really have anyone in particular to blame for it. I was getting migraines and my shoulders were thickly knotted all the time. I never felt relaxed. And I noticed I wasn’t getting enough exercise. And then I realized that it was because I never fully ended my work day. And it wasn’t helping me perform any better. In fact, I think it was making me more scatter-brained than ever.

I work remotely for Treehouse. We use HipChat to communicate. I start my work day sometime between 8 and 9 in the morning EST. And I end my work day between 5 and 6 in the evening EST. It started subtly. I was working through lunch. Then I wouldn’t close HipChat in the evening. I would leave it open. As long as I stayed on the computer, which I often use for personal reasons in the evening, I’d continue to get notifications any time someone messaged me or mentioned my name. Even if it was 10PM my time. I’d get sucked in and involved in whatever was going on and find myself working weird hours in addition to working a full day already.

I also would continue to get Github e-mail notifications in the evening or during my lunch. While walking to dinner with my boyfriend at 7PM one night, I felt my phone buzz and saw I had an e-mail related to a Github PR. I excused myself and then looked at it. Which is kind of rude. And I then got really annoyed. Of course, it could wait until the next morning, but when it’s thrusted at you, it’s really hard to ignore it. And because of that, the PR was in the back of my mind all evening and I couldn’t give my full attention to anything else.

I was so stressed out that I went to my manager about it. “I’m having a hard time. I want to be helpful and go above and beyond but I’m having a really hard time when it feels like I’m constantly reacting to everything” And his first response was, “You need to close HipChat at night.”

Being a Superhero By Destroying the Superhero

I took a series of directional changes in my day-to-day schedule and am happy to say that, so far, it works. To speak like an annoying meme, you have to give yourself time every day to “do you.” You will–eventually–have a nervous breakdown if you don’t. I’m fortunate that I recognized these issues before I got destroyed by them.

The biggest of these changes took some customization. I couldn’t figure out a way to turn off Github notifications that wasn’t an outright inconvenience. Turning on “Do Not Disturb” mode (or as I call it: “Crescent Moon Mode”) in iPhone was annoying because I wanted to get notifications for personal e-mail, text messages, incoming phone calls, social media, and other things. And my Github account linked to Treehouse is also my personal Github account, so all e-mails sent to it were going to my personal g-mail account, also very annoying.

Here is what I ultimately ended up doing. Which I don’t think is completely obvious:

  1. Github allows you to set up custom routing for e-mail notifications (link requires you to be logged in to Github)

Screen Shot 2015-09-21 at 2.22.26 PM

With this, I still get e-mail notifications for personal Github projects to my personal gmail account. But any activity that takes place in a repository owned by Treehouse now gets sent to my Treehouse e-mail account instead. This is a feature that I was not aware of until a few days ago and I wouldn’t be surprised if others were not aware of it either. Basecamp recently offered a way to automatically disable notifications between certain hours and I long for that same behavior in Github but until it exists, this works fine.

2. IMG_8842

I use the official Google Mail app. In the settings for secondary e-mail accounts, you can disable push notifications for anything except for e-mails flagged as “important.” I then set up a filter in my e-mail to ensure that arbitrary Github notifications never fall into this category. I continue to have my e-mail open on my computer (except after hours) so that these rules don’t affect that, but when I am out on the go, I no longer get random buzz-assaulted by a slew of comments on a PR.

3.  I close HipChat/online work chat. I was skeptical about this. Surely, there’s no difference between being flagged as “Do Not Disturb” and being offline, right? There is though. I find that people treat “Do Not Disturb” as a way to facilitate asynchronous communication (“Message me when you’re not busy and we can talk about this…”) whereas people generally do not message you at all (unless it’s an absolute emergency) when you are offline. Obviously, culture varies from company to company, but this is my own observation.  I think this is because “Do Not Disturb” communicates “I am here and will eventually be free sometime soon” and being offline sends the message that there is a really strong chance you are nowhere near a computer and are unable to talk–which is an absolutely okay place to be at 8PM on a Friday night.

4. I end my day by thinking of the next day. What things will I do tomorrow (or Monday)? If something less than ideal happens, what can I do to make sure it goes more smoothly if it happens again? This one is a bit new to me. It sounds like new-age meditative type nonsense, but spending just 10 minutes mentally wrapping up my day (and writing it down) seems to make it a lot easier to walk into the next day than spend the same amount of time reactively trying to remember all the loose threads of the day before.

5. I close out all the various work-related applications I use. This includes any terminal windows, editors, any browser tabs pointing at my local dev environment or Github. It all goes and my laptop returns to its ordinary non-work mode in which I chat with friends, play games, write things, and browse non-work websites.


I saw a few different conversations emerge from this article that brought up interesting other related things. One is the idea of not using the same device for work as you do personal things.  I think this is increasingly less common though with remote work. I don’t have an office I go to every day where I keep my “work” computer. My office is just as much my couch as it is some coffee shop in Reykjavik, Iceland.

In my previous job, I had a company-issued laptop and a personal laptop. And I traveled a lot all over the world. And it was very frustrating carrying two laptops because I’m a pretty small lady!  First world problems? Yes. But I’d rather squabble over the mixing and mingling of business-related applications and personal things than suffer sore shoulders all the time.

The second thing that kept coming up was the idea of working during your personal time off. I don’t think I have ever officially Worked™ while taking time off work, but I’m guilty of checking e-mail and getting all strung out over “oh my god someone is touching my PR–why? what? what are they doing? why is this happening?” or “What happened during this meeting that I missed? Were important decisions made without me?” I don’t really think this behavior is in alignment with “Superhero Mode”. It’s more the result of a person having control issues (note I didn’t say developer, because it’s not strictly a developer problem). I think allowing yourself to stop being a helicopter mom to your own job gives you a sense of trust that you can walk away for a moment.

What things do you do to disconnect at the end of your day? What things do you do to help you reconnect the next day? Have you experienced Superhero Mode before and if so, were you also a victim of Imposter Syndrome? Comment below.