Ruby on Rails Legacy App Modernization: Upgrade or Rebuild?
Hi, I am Serhii Koba, Ruby Team Leader at MobiDev. Over the past year, many clients addressed us with the request for updating Ruby on Rails-based applications. And yes – modernization is possible! Having an outdated Ruby software 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 below our approach to modernizing legacy Ruby on Rails applications.
If you have a specific question about your project, don’t hesitate to contact us and discuss it. It’s possible to meet in person with the Ruby Team Leaders in the USA, Canada, the UK, and European Union.
Contact us if you are ready to reanimate your Ruby project!
How We Handle Ruby on Rails Legacy App Modernization
At MobiDev, we handle the upgrade of a Ruby on Rails-based app in the following way:
- Assign a Tech expert
- Perform the full project code and infrastructure analysis
- Identify and prioritize the critical issues to be fixed
- Come up with a timeline and strategy for the project modernization. It could be a gradual evolution together with further features development
- Provide the team to do the modernization
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 software development 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.
10 Signs That You Need to Modernize Your RoR App
Not sure if it’s time to upgrade your RoR application? Read the 10 signs that it should be done.
1. Your web application needs updating if you have any of the following issues:
- Outdated and non-interactive UI, problems with UX
- Web app feels like it’s from the 2000s
- The web app makes the full page reload on each user click
- UI has no immediate response to actions
- Some interactions are impossible to implement
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
- Web pages are loading slowly, so users need to wait a lot
- The web application is unresponsive and annoying
Why does it happen?
web 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)
- No clear view of data flow in the app
- No vision of how users behave
- Lack of understanding of how to formulate Key Business Indicators in real-time
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. Web application crashes during rush hour
- The web application cannot handle a big amount of users
- Different parts of the system produce a different load, but cannot be scaled separately
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. Your 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 web development.
6. Increased infrastructure costs
Your web application 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
- Implementation of the new feature takes a lot of time
- The web development is slow due to high code coupling
- The deployment is hard and fragile due to huge amounts of bugs, testing, and fixing which requires additional efforts
Is your current development 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 RoR app modernization.
8. Each release brings a huge pile of new bugs
- New features break existing ones
- A lot of regression testing is needed by QAs
- No possibility to make frequent releases
How to stop it?
It’s time to perform Ruby code modernization.
9. 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.
10. You worry about security or can’t find engineers for the project’s tech stack
- 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, there is a risk to be sued if there is a data leak.
- Project parts and services are established on different technologies.
What to do to sleep well again?
Hire a development team, which will perform the audit and carry out the required changes to ensure your RoR application security: update all libraries, encrypt user data at rest and in transit, and implement end-to-end SSL. Sometimes rewriting parts of the app to use the same technology stack might be a good option.
We can handle all the stages of your Ruby on Rails app modernization
What to estimate in the process of Ruby on Rails app modernization?
- How will modernization influence the development of new features? Should all the development team be involved in modernization or is it better to have dedicated developers? When is it time to do the code freeze?
- Is the code ready for modernization? The features are covered with tests, documentation is in place, backups and disaster recovery are functioning properly.
- What are the goals of modernization? The team should set understandable and trackable performance indicators of modernization and regularly assess how the process is moving.
- Is the risk of modernization warranted? Modernization is an improvement but everything has its cost. Modernization plans should cover the increased risks of developer error (automation is required), rising complexity (more documentation to onboard new developers needed), etc.
Our Case Studies for RoR Legacy App Modernization
Here you can read three case studies, where outdated Ruby and Ruby on Rails applications were modernized, and one case, where RoR 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 Ruby developers involved in the project.
Case Study #1: Updating Legacy Ruby on Rails Web Portal
MobiDev worked with a credit reporting and collection company to improve their existing product. The client’s request was to upgrade the RoR legacy web portal to a newer version and fix bugs.
- Upgrade the version of Ruby on Rails and Heroku service
- Perform complex bug fixing
- Create detailed tech documentation
Upgrade Ruby on Rails and Heroku Versions
Our developers have ensured the stable operation of the portal by updating code from Ruby 2.5.8, Ruby on Rails 184.108.40.206, and Heroku 18 Stack. It took us only 3 months to successfully complete the full system update.
Perform complex bug fixing
As our developers were working towards upgrading the original version of the software, they came across a multitude of bugs that required attention in order to ensure the optimal functioning of the system. The development team prioritized the identified bugs from minor issues to more complex ones and gradually fixed these problems. We conducted regression testing to make sure that the upgrade didn’t affect the operation of existing features and that everything worked as it should. Last but not least, the team developed a set of automated tests to make it easier to perform upgrades in the future.
Composed detailed project documentation
The creation of technical project documentation at each stage of the RoR application upgrade was an important task. So our business analyst created a document with detailed functional requirements that outlined the intended behavior and functionality of the portal. This document greatly simplified the testing of the software in the current release and will be a reliable basis for future product improvements.
The client was satisfied with the prompt work of the team and recommends MobiDev for cooperation.
Full Case Study:Ruby on Rails Legacy Platform Upgrade
Case Study #2: Refactoring Legacy Healthcare 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.
- Upgrade Ruby and Ruby on Rails versions
- Define the set of patterns and abstractions to be used during the refactoring stage
- Make sure the new version of code is developed in an extendable way
- Provide a high level of security and personal health information (PHI) protection to comply with HIPAA
- Setup performant and easily scalable infrastructure
- Document the architecture design
- Develop a new set of features and launch in half a year
Upgrade to Ruby 2.7.1 and Rails 6.0.1
The first task performed by the Ruby development 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 Ruby on 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 development 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 #3: Upgrading Sports Tournaments Management System
MobiDev’s Ruby developers 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.
- Move the code to Service and Query Objects plus Decorators by introducing a Domain Driven Design (DDD) approach
- Unify the frontend part
- Make onboarding for new team members and developing of new features seamless and fast
It was decided to:
- Move logic from controllers to Service Objects
- Move query functions form models to Query Objects
- Move helper functions form models to Decorators
- Upgrade Rails version
- Develop all Front-end features using React
- Unify code style using Robocop and Rails upgrade
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 RoR 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 development 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 #4: 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.
- Provide migrating from AWS to Azure
- Improve legacy code base
- Find out how to solve other tasks related to risks encountered by the team
After investigation, the following problems were found:
- A lot of load from periodic computations
- At the initial stages, quality was sacrificed for speed
- Hard to extend and maintain code base
- Slow tests (harder to develop and release)
- Hard dependencies between system components
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 application 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 the Ruby on Rails developers to speed up automated tests and increase the extendibility of the legacy monolithic Ruby code.
I’ve been working on the project for more than four years. Along with the Ruby 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.
I am located in Toronto, Canada, so contact me and let’s meet in person to discuss your project.
It’s time to modernize your Ruby on Rails application!
Case study #5: WordPress-based Legacy App 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 development 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.
- Unifying the tech stack
- Isolate multiple apps from each other
- Reduce release risks
It was decided to:
- Rewrite the WordPress part of the project using RoR for unifying the tech stack.
- Introduce Microservices architecture to keep multiple apps isolated from each other and make it possible to share the data between them (like users). This increased overall stability and performance.
- Introduce CI/CD automation for reducing release risks.
Why Use Ruby on Rails in 2023?
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 a “swiss knife” of web development that allows us to create prototypes, proof of concepts and MVPs fast and test the market with a minimum budget.
- Ruby on Rails framework has built-in tools out-of-the-box to fulfill 80% of common web systems feature requests.
- For developers with the right skills, it is still a tool for infinite product growth in terms of features and code.
- Ruby on Rails makes both businesses and engineers happy. It was built with the philosophy “to make developers’ lives easier” in mind, which simplifies delivering new features and meeting product owners’ expectations.
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.
So, are you ready to modernize you legacy RoR application?
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 Ruby team throughout the years in web application development.
Book a call with a MobiDev’s representative in the USA, Canada, the UK, and European Union
+48 790 675 136 (EU) 10 a.m. – 7 p.m.
+1 267 944 6127 (USA/Canada) 10 a.m. – 7 p.m.