Lessons to Continue Learning When it Comes to Software Development
A quick walk through the biggest software development lessons I've learned as an intern
A female programmer by Joonspoon is licensed under CC BY-SA 4.0
Over the course of my summer at Collective Idea, I’ve been learning and growing as a software developer every day. However, sometimes I found myself running into a problem, learning how to solve it, and then struggling with the same problem a few weeks later because I completely forgot what I’d learned last time.
They say repetition is one of the most effective teaching tools. So I thought I’d use the story of a pairing session I had a few days ago to repeat and share a few of the most important lessons I’ve learned and relearned over the summer.
Denise, another software developer at Collective Idea, and I were pairing together to add a feature to Blackbird RSVP. The goal of this feature was to let an event host alert their guests to any changes made to an event. When a user updates the information for an event they are hosting, they should be taken to a page where they can send an email to all of their confirmed guests, letting them know changes were made. This page needed to do three things:
- Render an example of what that alert email would look like
- Offer users the ability to send or not send those emails
- Only appear if the event had confirmed guests attending
That’s not an impossible task by any means, but it definitely isn’t a simple one either. It would be pretty hard to try and tackle all of that at once, which brings us to my first lesson.
1. Break big tasks down into smaller ones
We took that story and split it up into smaller goals. Our list ended up looking something like this:
- Create the route to this new page
- Only navigate to the new page if the event has confirmed guests
- Display a preview of the alert email that lists the old event information and the updates details
- Let the user indicate whether the update emails should be sent
This list breaks down a large and complicated story into a series of smaller, more manageable steps. Each step built on the last so we had a clear road map of how the story should progress. Now that we had a plan, we started work. We created a new page, added a check to make sure users were only directed to the page if the event had confirmed guests, and then we turned our attention to the emails.
The emails posed an interesting problem because they required access to information in an
Event object that had already been updated. We needed to persist the initial contents of its fields so that we could compare it to the new data in the email. Unfortunately, neither of us knew what the proper conventions may be for that kind of data workaround.
2. Ask for help
No, seriously. Ask for help.
If you don’t know how something in the code base is working, or you’re not sure where to even begin when it comes to tackling a problem, ask someone to help you. At the very least, try and find someone who might have experience with a similar problem, and ask for their advice.
The general limit that I’ve been advised to set for a problem you’re trying to solve is 30 minutes. If you’re stuck on a problem longer than that, stop right there and ask for help.
Since we had two minds working on the problem, we gave ourselves a little more than half an hour. After a few failed attempts to store and persist the details of an event before any changes were made, we finally caved and asked for help. That’s when we were told that the app was already using a module that would easily let us access that old data.
Neither of us had ever heard of Rails’
ActiveModel::Dirty module, and we were surprised to find out that we could just call a method and get the initial field values for a “dirty”, or edited but unsaved,
So now we were able to pass in a hash of the event’s old details along with the updated
Event object to render a preview alert email. We still had to display that data somehow.
3. Talking solves problems
I had very little experience in pair programming before coming to Collective Idea, but it’s quickly becoming one of my favorite ways to program. You’re constantly reviewing each others code, looking for oversights in logic, and also acting as a soundboard for each other while struggling to debug a problem.
A problem like “How do we format this hash of data we have when the only data-formatting methods are in the
event_decorator?” for example.
As someone who had never worked with decorators in Rails before, it was an especially confusing problem. Fortunately, I had a pair partner. Denise was able explain to me what a decorator is, and how we use an
event_decorator to provide formatting functionality to
Event objects to display the event’s data in a view. Through her explanation, and my additional questions, we came to the conclusion that we could store the old data in an unsaved
Event object. Then we could make a decorator from that unsaved
Event object and use the decorator methods to format the data for display in the email. This approach worked, and the email preview rendered with no problems.
So we added a few buttons to the page to let the user choose whether or not to send the emails. Clicking either button would redirect users to their dashboard, but clicking “Yes” would also trigger the Mailer to queue the alert emails for sending.
4. Google is your best friend.
What actually happened was clicking “Yes” threw an
I’d never seen this error before, but a quick Google search told me that it had something to do with Rails’ Global ID system. When we investigated the Mailer, we realized that this error was only being thrown if the emails were being added as
.deliver_later. Another Google search on the difference between
.deliver_later also mentioned the Global ID system. Specifically how only
.deliver_later uses Global IDs to retrieve the parameters that have been passed into the call to the Mailer.
Because of this new found information, we realized that some object we were passing into the Mailer didn’t have a Global ID.
5. Read the entire error log
I know that sometimes it’s hard to read back through a stack trace in order to figure out exactly where things blew up. Sometimes you think you’re absolutely positive that you know what’s causing the error this time, so you don’t even bother looking at the log.
Error logs are there for a reason though. Not only should you read it, you need to make sure you’ve read all of it. Read the error log out loud if you have to, just to make sure you know exactly what it’s telling you.
We did not read our error log right away, at least not all of it. Because of that, we knew that we were dealing with an
ActiveJob::SerializationError, but we didn’t know that it was caused by a decorator, and not the unsaved
Event object that we spent the next hour bending over backwards to avoid using.
If we had read the entire error log, we would have known immediately to look at our decorators more closely. We also would have realized a lot sooner that Draper, the gem we use to generate our decorators, creates decorator objects that don’t have Global IDs at all. The Mailer can’t deserialize an object that has no Global ID, and so an
ActiveJob::SerializationError was thrown.
Eventually, we did figure the problem out. We worked out a solution involving not passing the event to the Mailer at all and instead retrieving it using its relation to another object we were also passing in. We definitely would have solved our problem a lot more quickly if we’d taken the time to read the entire error message Rails was giving us.
6. Never Stop Learning
All of this happened in just one pairing session. When working in the software development industry, it’s more or less a job requirement that you’re able and willing to learn constantly. Technology keeps advancing, changing, and developing, and someone has to keep up with it all. Whether it’s a new language, a new platform, or a just a new approach to development, there’s always going to be something new coming our way. That’s why in the end, being a software developer means you never stop learning.