Contact Us

How To Upgrade Ruby on Rails Legacy Applications

Ruby on Rails | September 1, 2021

Since 2004, Airbnb, GitHub, Zendesk, Shopify, Kickstarter, UrbanDictionary, CrunchBase, and hundreds of amazing products, including yours, have been built with Ruby on Rails.

Is Ruby on Rails dead in 2021? The language has recently offered some reasons for developers to consider migration to different tools.

In 2020, Ruby was still loved by 42% of developers. Why? Because it was built with the key thought in mind that it could “make developers’ lives easier”. Development with Ruby was fun, interactive, and fast. Nowadays, it is hard to imagine a development task for which there is no existing Ruby library.

Over the past year, several clients addressed us with the request for updating Ruby-based enterprise products. And yes – modernization is possible; having an outdated Ruby product doesn’t mean it should be rebuilt from scratch with different technology. We believe that in most cases it is possible to work with existing legacy code, and we’d like to share our approach to modernizing legacy Ruby / Rails applications. Read on, if you endeavor to reanimate your Ruby-based project.

When You Need to Modernize Ruby / Rails App

1. Your application needs updating if you have any of the following issues:

Why is this a risk for legacy systems?
Improving user experience (UX) is usually considered as a designer task. It is important to know that modern UI/UX tools require both frontend and backend enhancements.

2. Slow application performance

Why does it happen?
Application architecture and database schema design are complex and time-consuming engineering tasks. In the early stages, serious investment is perceived as high risk because the product may not succeed. Subsequently, code refactoring becomes a challenge at the later stages.

3. Unable to track Key performance indicators (KPI)

What is missing?
A data warehouse module! To support your marketing and business team, you need a solid engineering solution to gather data about your business and transform it into human-readable numbers and graphs.

4. Application crashes during rush hour

What does this mean?
The system has a bottleneck, which influences the whole application. Bad news: a short-term solution for fixing the bottleneck is not enough in this case. In the long-term, you should consider creating a mechanism to individually boost (scale) your key features.

5. My product is really a set of multiple apps

You can clearly see the way to move forward with Service Oriented Architecture, but do not know how to split the existing Monolith while keeping business running.

What is wrong?
Keeping all the apps in a single code base is like keeping all animals in the zoo in the same cage. It creates a lot of mess and unexpected bugs, slowing down development.

6. Increased infrastructure costs

Your web app needs a lot of cloud resources and expensive servers to operate due to non-optimal implementation.

What to do?
Consult with an experienced solution architect and come up with a technical modernization plan for the next phase of the project.

7. Engineers started to work slowly

Is my current team bad?
Not necessarily, but it requires professional help to identify what slows them down and come up with a plan for how to implement modernizations.

8. Each release brings a huge pile of new bugs

How to stop it?
It’s time to perform code modernization.

9. I cannot find engineers for the project’s tech stack

How to proceed?
It is painful, but sometimes rewriting parts of the app to use the same technology stack might be a good option.

10. I am worried about security

The first version was developed in a hurry with lots of bugs and minimal testing. Now that a lot of users have started using the app, I am worried that I will be sued if there is a data leak.

What to do to sleep well again?
Update all libraries, encrypt user data at rest and in transit, and implement end-to-end SSL. Or hire a team, which will perform the audit and carry out the required changes.

11. Mobile app integration is hard to implement

The project does not have an API, or it requires duplicating a lot of code and bugs.

Why is it so hard?
MVP or the first version of the project was developed without taking into account the possibility of a mobile version. It is hard to reuse existing code in the mobile app.

How to Handle Ruby on Rails Legacy App Upgrade

Ruby on Rails (RoR) upholds requirements for startups and MVP projects, due to its strong points, such as a fast time-to-market and a large community of developers.

Using RoR, a team of any level could start a project and develop it at the initial stages. This becomes a problem when your business grows – performance, scalability, security, and tracking come into play. At this stage, you need a more experienced team that is able to investigate, develop, and consult. Upgrades may be necessary either in this situation or when the Ruby on Rails application becomes obsolete.

At MobiDev, we handle the growth of a Ruby on Rails-based project in the following way:

What to estimate in the process of modernization

Ruby on Rails Legacy Application Update Case Studies

Here we will overview three case studies, where outdated Ruby and Ruby on Rails applications were modernized, and one case, where Ruby became a solution for modernization of a legacy software system initially built with another programming language. Three of the four case studies are accompanied by comments from developers involved in the project.

Case Study #1: Refactoring Health Legacy Application

The project was inherited from another development team after five years of development. So, it was a legacy code. It had outdated versions of Ruby and Ruby on Rails, and the code was written using many different architecture approaches mixed in a single codebase. There was no related documentation whatsoever.

Challenges

Upgrade to Ruby 2.7.1 and Rails 6.0.1

The first task performed by the team was to ensure that upgrades wouldn’t break the existing functionality. We developed and refactored 4488 automated rspec tests, which covered most of the existing application features. This step made it possible to upgrade Ruby on Rails to the newest versions safely. After the upgrade, the rspec tests showed us all the cases, where new libraries caused problems, and we managed to fix them.

Modular (Component) Monolith Rails architecture design

Although the Rails application had a single repository, by its true nature the application consisted of many different services. It was a real challenge to develop new features because of the way the code of all these services was mixed together.

After the brainstorming phase, the team decided to use Modular Monolith design for Ruby on Rails API. The benefits of this choice were that all services were decoupled into separate Rails engines (Admin Portal, CMS, Common API, etc.), it was easy to navigate the project and implement new features, and the design had a clear and easy to implement set of guidelines.

Building new infrastructure

Microsoft Azure was a great candidate for a new cloud enterprise solution. At that moment, it had a suitable bunch of tools to set up new infrastructure, taking into account security, scalability, durability, performance, and recoverability.

For security reasons, it was decided to implement an “End to End SSL” approach, which ensured that at any phase of communication between services the traffic was encrypted and safe. Azure Kubernetes service called AKS enabled achieving required scalability, durability, and performance for our Ruby on Rails API.

Last but not least, the whole setup was performed using the Helm tool and Azure DevOps CI/CD.

It was a real challenge to work on the healthcare project that was passed to MobiDev’s Ruby Team from previous developers without proper documentation.

During the project’s 2.5 years, we were doing a major upgrade and developing a product by adding new functional modules. A major upgrade included refactoring files, moving business logic operations to Trailblazer and database queries to a separate repository. Following Domain-driven design principles, we thoroughly covered both the new code and the legacy one with QA testing.

The project had quite a cumbersome monolith architecture, but we managed to divide it into several modules, using Rails Engines. To ensure proper code formatting, we applied Rubocop.

Case Study #2: Upgrading Sports Tournaments Management System

MobiDev’s Ruby Team dealt with competing objectives for this project. We had to develop more features in the same budget, reduce the number of bugs, and increase extensibility. Additional tasks included simplifying the onboarding of new team members and improving overall security.

Challenges

It was decided to:

Applying DDD allowed the developers to simplify overly-complicated models and controllers of the Legacy Ruby on Rails application and make sure it was easy to extend the code for new features.

The Rails app had 2 different ways to develop UI components: pure jQuery with Ajax and EJS with remote links. To unify the frontend part, we employed migrating to React.js as an appropriate UI approach.

Interesting technologies and a powerful team always motivate me. I was absolutely excited to work on the outstanding project which had no analogs, especially for kids, in that kind of sport. A lot of teams were involved to launch the mobile, desktop, and browser versions of the application. I am proud that we‘ve managed to transform the legacy project into the one with optimal architecture, totally covered with QA testing, and our API used only by GraphQL.

Case Study #3: Modernizing Bank Management System

Multi-tenant Ruby on Rails startup development had been running smoothly until the team faced several risks: slow response time under load, increased development time for new features, a single point of failure, and a lack of security mechanisms.

Challenges

After investigation, the following problems were found:

Migrating from AWS to Azure

The original first version of the system was built using AWS cloud in an outdated manner.

All developers had direct access to servers and databases, which is unsafe because of human errors and the high possibility of troubles that could happen from time to time. Also, servers were targets to crash because of periods of high load. The Ruby on Rails web app generated a lot of jobs and made the Compute Server (Sidekiq) get “stuck”. At these moments the whole system became unavailable due to the hard coupling of the components.

It was decided to perform a decisive technology modernization and also migrate to Azure.

Additional security mechanisms were implemented around authentication and authorization, applying Single Sign On approach (SSO) and Azure Active Directory (AAD). They were seamlessly integrated into the existing Ruby on Rails solution and Active Admin.

All the public traffic was routed through Gateway and Firewall for high protection of sensitive data. Key Vault allowed to store Ruby on Rails credentials and secret keys.

As the core of the system the AKS (Kubernetes) cluster was set up to provide the required value of performance and stability of the system, eliminating the single point of failure and providing a fault-tolerant experience for users.

Improving legacy code base

After the internal analysis of the code base, it became clear that to improve time-to-market for new features and reduce the amount of bugs, we had to get rid of monolith architecture and the server-side rendering approach.

The split to services and separating the frontend part drastically assisted Ruby on Rails developers to speed up automated tests and increase the extendability of the legacy monolithic Ruby code.

I’ve been working on the project for more than four years. Along with the team we’ve implemented the project features, using parallel computing, service architecture, and complex business logic. The project utilizes an advanced security system based on Azure, Kubernetes, and Helm. The tech stack comprises RoR, PG, Sidekiq, Redis, React, and Java.

It’s worth noting that the project meets the Accessibility requirements, has successfully passed Security Audit performed by the client’s IT department, and is under ongoing performance optimization.

The project is still being actively developed by the client, and my team participates in technical decision-making and developing of business logic.

Case study #4: WordPress-based Legacy Application Modernization with Ruby on Rails

RoR is still considered the best platform for startup product development, so sometimes it can become a solution for the modernization of a legacy software system built with another programming language.

The project was initially a WordPress based startup social network for teams interested in the growth of their businesses. Soon an idea of a special growth management tool came into play, and it could be built using Ruby on Rails framework.

The team quickly realized that the project was a set of multiple services, and it was difficult to keep engineers for different technology stacks (WordPress and RoR). In addition to the startup-based architecture design, it was hard to develop new features and the development slowed down.

Challenges

It was decided to:

Why Ruby on Rails is Still Our Choice in 2021

In summary, the increasing demand in web systems development raises the question, which tool is best suited for these needs? For us, Ruby on Rails is still a valid and preferable tool for the following reasons:

It is undeniable that Ruby on Rails has some drawbacks. One of them is the high price for each mistake. Errors originating from the planning stage or the first development phase are difficult to correct in the future. As a result, this turns into broken interactions between separate parts of the app. To avoid mistakes, you need to find an experienced team that is able to deliver the product with the required customization and functionality, devoting attention to previous research.

We are ready to work on challenging projects and believe that with a competent approach they are bound to succeed. For us, RoR is flexible enough in the long term, as well as secure and easy for business logic implementation. Ruby on Rails shines again with all its refactoring best practices gathered by the MobiDev team throughout the years in web development!

This content was originally published here.