What I Learned from My First Rails Upgrade
At OmbuLabs, one of our specialities is upgrading Ruby on Rails applications through our specialized service called FastRuby.io. In this post, I want to share with you some of the things that I’ve learned while working on my first Rails upgrade client project as a less experienced Rails developer.
Reading Ruby on Rails tutorials really didn’t prepare me for the upgrade process
Before I started with OmbuLabs, I was primarily a front end/UI developer, working on building webpages with HTML, CSS, and jQuery, and some light web application development with WordPress. Though I had a solid grasp of software engineering fundamentals through the curriculum at Launch School, and I had gone through several Ruby on Rails tutorials to prepare for job interviews, I found that building my own apps didn’t prepare me for the upgrade process. With my own applications, I got to start from scratch using the latest tools in the Rails ecosystem. On the job I had to wade through large legacy applications that hadn’t been upgraded in years.
Luckily my teammates had already written tons of articles, as well as an eBook, about FastRuby.io’s upgrading philosophy and process. I tried to read as many articles as I could before the client project started. But until you go through the process a few times, that knowledge is purely theoretical.
I naively expected the upgrade process to be straightforward. FastRuby.io’s first step before any upgrade happens is called the Roadmap process. In this process, we work with our client to get access to their code, test suite, and build processes so we can examine the app in the following ways:
- First, we start by “dual booting” the app, which means that we use a gem that FastRuby.io maintains called next_rails that allows us to run the existing application code with the next version of Rails. We do this to determine whether the app runs successfully or not, and we take note of what error messages and deprecation warnings we find.
- Second, we run the code through a few code analyzers, namely skunk and codecov. We do this to get an idea of the current test coverage throughout the application, and to examine the code complexity. We use audit to generate a report of all the gems used in the application, complete with a report of each gem’s security vulnerabilities with links for each CVE found for that vulnerability.
- Third, we look through the Rails Upgrade guides and the release notes for the target upgrade version, to look for important information pertaining to API removals, deprecations, or other gotchas.
These findings become a report with a list of action items for the upgrade. On the surface, many of these action items look simple to the untrained eye- a matter of finding and replacing deprecated methods or syntax, or upgrading a gem or two. What could go wrong?
The importance of having a good test suite
Well, I learned very quickly what could go wrong. Trying to upgrade outdated code while also trying to avoid introducing extra errors to the test suite of a codebase you aren’t familiar with is like building a house of cards - one wrong move and the house comes crashing down. I tried to be mindful of the test suite as I submitted my pull requests, but many times I did not understand whether the test suite failures were a result of the code I changed, or whether it was due to an issue in their tests. I quickly realized why OmbuLabs prefers to take on projects that have at least 60% of test coverage. If you don’t have an automated way to determine whether your app is working correctly in the first place, it’s going to be very difficult to figure out if everything still works the way as expected after the upgrade.
Double check your work
I had some issues with some of the tasks that I thought would be ‘easy’. One ‘easy’ task in our upgrade plan was running the
rake rails:update task (the equivalent of
rails app:update for earlier Rails versions). The goal for this task was to run
rake rails:update to create a list of updated config files for Rails 4.0. Once I had an idea of which config files would be updated in 4.0, I could compare them to my current ones for 3.2. Then I could manually update the config files to be compatible with 4.0 without removing all of the custom configuration that
rake rails:update automatically removes. Unfortunately this process was not as straightforward as I had hoped. After running the Rake task, I had a list of config files files I knew I could update, but I didn’t understand what the configuration was doing and why it was changing.
When it came time for me to update the config files for 4.0, I tried to be conservative about what to change so I didn’t end up with a broken test suite. For example, I obviously knew that completely deleting the
config/routes.rb file would be a bad idea, even though that’s what the
app:update task suggested. But for other, less obvious changes, even after consulting the Configuring Rails Applications guide, I wasn’t entirely sure that I wasn’t changing anything drastically. So I wasn’t too surprised when I created the PR and found that the test suite was broken. I reverted some config changes, hoping to fix the problem, but it didn’t. Eventually one of the senior engineers working with me on the project found out that I had added some asset configuration that wasn’t appropriate for the application. It was slightly embarrassing, but an important lesson on why to be careful.
The importance of git
Even though my git skills have treated me well as a solo developer, and for 90% of my use cases as a developer working in a team, I quickly discovered that I could stand to upgrade my git game a little bit. I struggled with rebasing branches, and watching the other developers cherry pick commits to add to new PRs made me nervous. I had at least one or two instances when I called one of the senior developers I was working with in a panic because I thought I had messed up rebasing a branch. Each time, they patiently walked me through the process, answering my questions as we went along. I realized that I didn’t have to fear rebasing, and by the end of the project I was cherry picking commits with confidence.
The most important thing I learned
The most important thing I learned during this project is that it’s important to ask questions and to lean on other developers on my team who have more experience than I do. In my past role, I was the only web developer in a digital marketing team. I wouldn’t have anyone to ask questions to even if I had wanted to. But I found that in a Rails upgrade, it’s important to rely on my team’s judgment and past experience because it’s not always clear what the solution should be.
I learned a lot from my first client project - I got more insight as to why our upgrade process is structured the way it is, ways to improve my own work, and the importance of working together with my team. I can’t wait to take what I learned and apply it to my next client project.