Introduction
Upgrading a legacy Rails application can be quite challenging. At times, it can be overwhelming to determine the starting point. Completing the Rails upgrade may require a significant amount of time, perhaps even extending beyond a single sprint.
Here, I will outline the steps I take when approaching this task. We will explore the crucial factors that should be considered before commencing the work.
Test Units
When it comes to upgrading a Rails app, test units serve as the primary tool. They play a crucial role in identifying which lines of code, gems, and other components require updates.
Prior to embarking on any upgrades, it is essential to ensure that your test units achieve a minimum test coverage of 80%.
To facilitate this, SimpleCov can be employed as a code coverage analysis tool for Ruby. It leverages Ruby’s built-in Coverage library to gather data on code coverage.
App Update
Rails offers a useful tool designed to assist in upgrading your Rails application to the desired version. [Rails upgrade tool (https://github.com/rails/rails_upgrade)
There is also Rails upgrade gem if you are on Rails 2 or 3.
These tools inform you about the files that require upgrades. However, it’s important to note that these tools overwrite your Rails configurations with the configurations that come with the specified Rails version.
To preserve your application configurations, it is necessary to make a copy of your application configs from your repository before proceeding with the upgrades.
Ruby Version
During the process of upgrading a legacy Rails app, it involves transitioning from one Rails version to another until reaching the latest version available.
It is crucial to be aware of the compatible versions of Ruby and Ruby gems associated with each of these Rails versions. [Ruby & Rails Compatibility Table (https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html)
Upgrading Rails and Dependencies
To begin with, it is crucial to install and utilize the appropriate Ruby version for your desired Rails version. Please refer to the “Ruby version” section for guidance on this matter.
I strongly advise using rbenv or rvm, as they provide convenient tools for switching between different Ruby versions.
To facilitate RVM in automatically switching your Ruby version when you navigate to your Rails root directory, you can create two files: .ruby-version and .ruby-gemset.
From my personal experience, I have found that updating the Rails version and Ruby version directly from the Gemfile is not an advisable approach. This method often results in numerous dependency issues when executing the bundle install command.
Let’s consider an example where you currently have a Rails 2 application and you intend to upgrade it to Rails 3. The approach I follow involves creating a new Rails app using Rails 3.
In my Rails 2 app, I begin by commenting out all the contents of the Gemfile. Then, I copy the entire contents of the Rails 3 Gemfile into the Rails 2 Gemfile. Afterward, I execute the bundle install command.
Once this step is complete, I systematically comment out each line of gems in the Gemfile, running bundle install after each modification.
To ensure a smooth upgrade process, it is crucial to proceed gradually by commenting out only 2 or 3 gems at a time. This allows for identifying any potential dependency issues that may arise and facilitates the upgrading of those specific gems.
Then, update the contents of .ruby-version and .ruby-gemset.
echo '2.0' > .ruby-version
echo 'anything-here' > .ruby-gemset
In many cases, even if you have successfully installed a gem without any issues in the new Rails version, there may still be instances where you need to upgrade the gem’s version. This is because certain syntax within these gems may not be compatible with the new Ruby version you are using.
To determine which gem version is compatible with your Ruby version, you will need to visit the repository of that gem and examine the gemspec file. Within the gemspec file, you will find information regarding the required Ruby version for each version of the gem.
To find a compatible gem version, you can search through the git tags of the gem repository until you come across a version that matches your Ruby version.
Upgrading Syntax
After completing the bundle install command without any issues, you can proceed to identify lines of code that require syntax updates.
Running your test units is a critical step in this process. It is expected that a substantial number of tests will fail, necessitating the rectification of both the test syntax and the associated lines of code to achieve passing results. It is imperative to refrain from altering the original test cases while making these adjustments.
Continue this iterative process until all tests pass successfully and you can run the Rails server without encountering any issues.
Regression Testing
In addition to test units, performing regression testing is essential to ensure that everything functions as intended before the upgrade.
To conduct regression testing, it is advisable to identify both the major and minor features of your application. You can create a spreadsheet to document this information, using the following columns:
- Feature: Name of the feature.
- How to test: Describe how to use the feature, including any edge cases that should be tested.
- Result: Indicate whether the test passes or fails.
- Remarks: Include any important notes or observations regarding the feature or the test results.
- Tester: Name of the tester.
By systematically going through each feature and performing the designated tests, you can verify that the application is functioning correctly after the upgrade.
Conclusion
Upgrading a Rails application may not be as challenging as it initially appears. With the right tools, approach, and dedication, anyone can successfully navigate through the process of upgrading their Ruby versions. The reinteractive upgrade service can help you with the process and get you onto the latest version with minimal downtime or issues.
Based on my personal experience, the following are the recommended Rails version transitions when upgrading from Rails 2 to Rails 7:
- Rails 2 -> Rails 3
- Rails 3 -> Rails 5
- Rails 5 -> Rails 7
By following these incremental Rails version upgrades, you can ensure a smoother transition and minimise potential compatibility issues.