Our rating engine gets a lot of love and attention from the engineering team at Simply Business. After all, it’s an integral part of our insurance platform. Back in the day, our platform was growing so rapidly that we decided to extract the rating code from our main application into a gem. In this way, the rating gem could be used anywhere it was needed – in our monolithic Rails application, as well as in other gems and applications in our domain. Problem solved.
But then we hit a new problem. What do you do when the name of the gem is based on an old pun that isn’t sitting well in a culture striving for inclusivity? Well, as it turns out, the answer is a bit complicated.
Unravelling complexity
You may be thinking, that sounds easy, just do a find and replace! And you wouldn’t be wrong. That is certainly a reasonable strategy, and one that was tried periodically. The problem was, this solution was never mergeable.
For context, our rating gem has around 250 – 350 branches, with anything from 50 of them active at any given time. Deploys are made a dozen times per day, and more. It’s a busy place! And like most Ruby gems, the name given to the top-level module is also the name of the gem. In our case, the name of the gem is referenced more than 7,000 times throughout the codebase.
Given the volume of branches and code, a big bang approach would have involved blocking deployments to allow every part of the codebase to be brought in sync – a step we didn’t want to take. But more importantly, this one and done branch would inevitably have merge conflicts from the very outset. Worse still, had such a branch been merged, it would have caused merge conflicts for every branch downstream. So we took that option off the table. Even though this approach seemed simple, it would have created too much chaos in a living, breathing codebase.
![sb-tech-site-technology](https://www.simplybusiness.co.uk/wp-content/uploads/sites/3/2024/05/sb-tech-site-technology.webp?w=768)
An incremental approach
When a big change to an existing codebase is on the horizon, I’m convinced that the most successful way forward is an incremental approach. A big problem is really just a bunch of small problems. So we asked ourselves – how can we break this down? The power of the Ruby language and Ruby’s popular linter, Rubocop, helped us do the following:
- We created an alias for the top-level module of the gem, naming it with what would eventually become the gem’s new name, simply writing
NewName = OldName
where it was defined. - We started changing some of the module references, in the gem itself and in our monolith, and were able to maintain a passing test suite.
Of course, new references to the old name were constantly being added to the codebase. We could have messaged everyone and asked them to start using the new name from now on. However, we wanted a more technological approach.
- We wrote a custom RuboCop that disallowed all references to the old name. We turned it on incrementally, directory-by-directory, and using the autocorrect option, it basically did our job for us. If anyone ran afoul of our cop, they simply had to run the autocorrect to be back in business.
Managing the unexpected
The most nail-biting day was when we renamed our top-level module to use the new name, and flipped the alias. We had to require the new module in the main application file in our monolith, application.rb
. Our test suite passed and everything seemed to work. Then we started getting reports that engineers couldn’t access their Rails consoles locally.
Well, that wasn’t expected. We figured out that due to variations in the order of file loading across environments, we needed to require our new module in different places in some environments. And this seemed to vary by engineer and was hard to debug, when, as the saying goes, “it worked on my machine!” Luckily, the very next day, we were updating the gem name itself, so time was on our side.
The rename of the gem was straightforward at this point. We renamed the gemspec
and updated our pipeline to publish the gem under the new name. We merged the changes and had no problems (and everyone’s consoles worked again!). All that remained was to clean up and remove the alias.
Takeaways
In all, renaming a gem that was embedded in so many of our applications was a big job. To touch so many areas of the codebase with as little impact as possible on other code and engineers was not easy, even if the premise seemed otherwise.
There were other details, such as fields in the database that we had to rename, that I haven’t mentioned in this post. But for me, the takeaways of undertaking such a task were both personal and technical. Personally, if even one more new joiner was made uncomfortable by our gem name, it would have been one too many, and I’m proud that Simply Business dedicated the resources to prevent that. On the technical side, the task of renaming our rating gem has reinforced in my mind that breaking down an engineering problem into the smallest possible steps is the path that’s most likely to result in success.
Ready to start your career at Simply Business?
Want to know more about what it’s like to work in tech at Simply Business? Read about our approach to tech, then check out our current vacancies.
We create this content for general information purposes and it should not be taken as advice. Always take professional advice. Read our full disclaimer
This block is configured using JavaScript. A preview is not available in the editor.