What Value Is A Ruby on Rails Code Audit?
Reading time: ~ 9 minutes
We help organizations with existing Ruby on Rails applications making them better and more maintainable. When organizations approach us, they often have a laundry list of improvements they would like to make to their app(s). Many of their early questions are focused on getting realistic estimates from us.
Those estimates are tough to provide.
Why is that?
"What seems to be the trouble?"
Modern cars are equipped with several sensors that regularly monitor and raise an alert when something is concerning. When your vehicle's check engine light turns on, you should bring it to a mechanic. Your mechanic can review the diagnostics and make some recommendations for you to address. Before that, if we didn't know how to work on our vehicle, we'd need to trust our mechanics to rely on their knowledge and debugging skills.
Working on existing software is similar. Despite ALL the software tools available to us to track errors, performance, and user behavior, these give us only part of the picture.
We might have experience building similar features for different clients, but while the underlying framework is a Ruby on Rails application, no two apps are the same.
Estimates without existing context are SWAGs. We can give you a broad range, but it'll come with many caveats.
Confession: This is why developers often start every answer with, "it depends..."
Over the years, it's been our experience that every project shows up with technical baggage (some of which our community refers to as 'tech debt').
Prospective clients understand that we'll need to take a look under the hood to acclimate ourselves and begin building context. Timeboxing ourselves is a helpful pattern to focus on what is most useful for both parties, primarily if the client is focused on modifying existing features and beginning to explore new ones.
We offer clients a fixed-cost price for this initial discovery engagement. In addition, we have tiered pricing based on the overall size of the Rails app's codebase and known dependencies.
How do we build context?
We run through an extensive diagnostic checklist that we've been iterating on since 2007. This checklist includes a long list of high-level that allow us to establish a baseline of what we might be working with.
Here are some of the topics that we dig into.
What's the state of your documentation?
Everyone will tell you that documentation is one of the most important things for your software project. I've been known to say it a few times, too. But unfortunately, it's often the easiest thing for developers and product owners to put off, especially when teams are small.
When new clients come to us with their applications, rarely is extensive documentation included. If little is documented within the code repository, we'll inquire about access to internal documentation tools (Google Docs, Confluence, Notion, etc.).
Here is a sampling of the types of questions that we're hoping your docs will be able to speak to.
- Why does this application exist, and for whom?
- What kind of data is this application responsible for, and how does data flow through it?
- What are some of the most critical pieces of the application?
- How does a developer spin up and contribute code?
- How are security credentials managed (i.e., for 3rd-party APIs and integrations)?
- What are some weird things that a developer should know about?
- When things tend to go wrong in this app, what are some step-by-step instructions for confirming and addressing them?
- How does one deploy changes for quality assurance, staging, and production environments?
- What automated tasks/jobs run behind the scenes without a human needing to trigger them manually? How will you know if they stop operating as expected?
For many teams, these details are spread across the brains of multiple people who’ve worked on the project, and they’re rarely written down. We audit this so that if/when we inherit your project, we'll have some open questions to start working to answer over time.
ProTip: If you're not confident that your developers have been documenting things, rather than ask them, "Where can I find our documentation?", you might consider asking them about specific types of docs like, "Where can one find setup documentation for our app?" or "Where can one find deployment documentation?"
Our experience is that if such documentation doesn't exist, it takes little time to reply with something akin to a helpful answer, AKA version one of some docs.
Walking through the steps of getting your application up and running is vital. In the best-case scenario, we can do this on a laptop in 20-30 minutes. Worst case, we hit pause after a full day of wading through issues.
Ruby on Rails has a typical pattern that most projects adhere to. Occasionally, some developers will get things up and running and never revisit the initial setup process themselves again. This means there are likely many undocumented changes they've made that only exist on their laptop. This is why it's essential to have documentation around this.
Some of this will require some trial-and-error and discussions with one of your developers--should they still be available.
There have been many scenarios where we didn't have that luxury and had to figure it out ourselves. If we hit our timebox, we'll revisit this in an upcoming project engagement.
ProTip: We encourage all developers to undergo this process at least 1-2x/a year. They should delete the app from their machine and attempt to follow the setup docs. Through this, they can address anything missing and remove instructions that are no longer relevant.
In 2022, in our biennial survey of 2,660 Ruby on Rails developers, 58% of respondents answered that some or none of their Rails projects were running on recently released versions of Ruby and Rails.
When asked, “Why not?” nearly 60% said, "Not enough time," or "Not considered a priority."
Read: When Should You Upgrade Your Rails Application?
Rarely do clients with existing apps come to us running on the most recent (and secure) version of Ruby on Rails. But we have plenty of experience with inheriting them and moving them forward.
If these aren't currently documented, we will capture this in the documentation for future reference.
It is a capital mistake to theorize before one has data. -Sherlock Holmes
One of the most critical parts of your app's environment is its data architecture. We dive deep into your database schema and try to make sense of the different data types, data validation rules, and associations with one another.
- Does your application replicate data to and/or from an external service?
- Is any of your data encrypted?
- Can we view highly private user data that we probably shouldn't be able to? (Should this be encrypted?)
- Are there areas of the database that track changes, and who made them? Are there areas that should have versioning?
- Is the database well designed?
- What are things named? Are tables and columns named sensibly?
- Are there any missing indexes that could help speed up performance?
- Are there any visual representations of your database architecture? When was it last updated?
This is generally where we gain a lot of context about your business domain.
Adherence to Rails community "Best Practices."
One of the reasons that Ruby on Rails was originally a breakthrough success was because it was designed with strong opinions about how a web application should be built. When developers align their approach with the community's best practices, we can speed up how quickly we acclimate ourselves to a software project. This is why we spend much of our code review process trying to understand your data architecture, business domain, and documentation.
Because, in theory, we should find associated code in your Rails application quickly.
- Our checklist has us dive into large areas of the codebase and conduct some pattern matching.
- Is code located in places we expect to find it?
- Is there code in areas where we wouldn't usually see it?
- What does the code itself look like?
- Does it look and smell like a typical Rails application?
- Does it feel like it was written by a developer who appreciates Ruby on Rails? Or does it look like it was written by someone who tried to get in and out of the codebase as quickly as possible?
An automated test suite is a collection of code that tests the desired behavior of an application (without requiring a human to test every bit of logic manually). This allows us to make changes and reduce the risk of breaking other areas of your software application, as we can re-run the tests.
So, we check to see if there are automated tests. Ruby on Rails provides us with a railroad track and a locomotive to which we can attach our train cars and caboose if we invest the time. There are metrics that developers can regularly track to monitor the code-to-test ratio.
Want to learn more? Read The Importance of Test Coverage for a Rails Upgrade
Aside from the previous versioning topic, we also evaluate how dependencies are currently being used and organized.
- Are there any docs that indicate what is being used and for what?
- Can any of them be removed?
- Is each of your external dependencies still being actively maintained?
This is often a big part of what goes into building some context.
For example, there are open source libraries that we would have used in an application back in 2012 but may have been deprecated in 2019.
- Are we needing to explore introducing new functionality to your application?
- Are we constrained by the limitations of a tool that the wider community has abandoned for a better solution?
- Or is there now a prerequisite to migrate from one library to another before we can build that new feature you're hoping for?
Along with how your application stores confidential and/or sensitive data, we also run your application through a series of tools to help us understand if there are some possible gaps in the security of your application.
Like the computing device you're reading this on, new security patches are being released regularly. We primarily focus on all of the code's dependencies in your application and can have the scanner tools used on all our client projects review yours.
We also check to determine if any security credentials are getting passed around, in plain text, within your codebase.
We will compile our findings, help you understand the severity level, and outline steps to remediate.
Hosting & Deployment Strategy
Most of our clients are now running their apps on some cloud-based services. Only a few of our clients have their Ruby on Rails app running on physical hardware in a server cabinet somewhere. We don't miss our trips to the server colocation on Thanksgiving Day to fix a physical.
Fun Fact: Planet Argon used to be one of the first web hosting providers to support Ruby on Rails—that side of our business was acquired in 2009.
During our audit, we review the documentation for deployments, gain access to accounts, review the current configuration and tooling, backup and recovery procedures, etc.
We'd be surprised if you were using something we have yet to have had some exposure to before. When that happens, we can assess whether you should keep it as is and/or know your alternatives.
Circling back to the beginning of this post, let's dig into whether your application has sensors in place. When something goes wrong, is that automatically logged somewhere? Or are you entirely reliant on a user sending in a support request? Our clients rely on several great third-party error monitoring and performance monitoring tools.
When we have these tools in place, we can react quickly to a bug as we'll have more details about what happened, to whom, and when so that we can attempt to reproduce and resolve it.
If a client comes to us without one, we recommend they use Bugsnag for bug tracking and New Relic for performance monitoring. We work with plenty of similar tools, too.
Outside of making sure you have some tooling in place, we will log into these systems and review what is showing up in each of them. It's common for teams to overlook these tools for a while, so some unaddressed issues might be worth evaluating.
Again, we'll assess and make our recommendations.
Our Summary and Recommendations
Once we work through our extensive checklist, we compile our findings into a document and/or a slide deck. We share the document before we dive into it together so you can review it and highlight questions you might be curious about for us to explain at a deeper level.
We then walk you through the high-level findings and demonstrate how much context we've gained through this process. We ask clarifying questions, take and answer your questions, and discuss our recommendations.
A great outcome here would be that we should be able to convey--with confidence--that your application is one that we can be successful with. Can we maintain and/or extend its functionality? What challenges might we face in both the near and long term?
Once both teams have a shared understanding of where things stand today, we'll be in a good place to start discussing those features you want us to explore building next.
These are traits of maintainable Ruby on Rails applications.
If you have a list of improvements you'd like to make to your Ruby on Rails app, but it feels like a little too much, we can help break it down for you. Click the link below to check out some of our service offerings or schedule a free call just to talk shop.