How and Why to Upgrade the Ruby Version in Your Project

Published by Moncef Belyamani on
Updated on

Most people who visit this article are either trying to upgrade the Ruby version on their Mac, or upgrade the Ruby version in their existing project. They’re both similar because the ultimate goal is to install a specific version of Ruby.

If you don’t already have a proper Ruby development environment where you can easily install multiple versions of Ruby, start by reading the first section below. Once you have a proper Ruby dev setup, read the rest of this article to better understand how Ruby versions work. If you already have a proper Ruby dev setup on your Mac, you can skip the first section.

How to upgrade the Ruby version on your Mac

One of the confusing things about working with Ruby on macOS is that it comes preinstalled with Ruby. However, this version of Ruby, known as the system Ruby, is not meant to be used for development. Even if it was a good idea to use the system Ruby for your own projects, you wouldn’t be able to update it directly.

The way you use different versions of Ruby is by installing each version separately, without interfering with the system Ruby. And the tool you use is known as a version manager. It allows you to install multiple versions of Ruby at the same time, and lets you uninstall any versions you don’t need anymore.

For more details, read my article that goes over 5 reasons why you shouldn’t use the system Ruby, and explains the proper way to install Ruby on macOS with a version manager.

Why people get stuck running old Ruby projects

A question I see often from Rubyists is, “How do I install older Ruby versions, like 2.6.x and 2.7.x?”, where the “x” is older than the latest supported version. They typically ask this because they’re trying to run an existing project (such as a Rails app, Jekyll site, React Native app, or other Ruby project) that specifies an old Ruby version.

For example, if the Gemfile and/or .ruby-version file is set to Ruby 2.7.0, they try to install 2.7.0 on an Apple Silicon Mac, but they get a compilation error like this:

linking shared-object zlib.bundle
make: *** [build-ext] Error 2
!!! Compiling ruby 2.7.0 failed!

And then they waste time looking up that error message or trying to find other ways to install Ruby 2.7.0. In this particular case, the issue is that Ruby 2.7.0 and 2.7.1 are not supported on Apple Silicon Macs. And this is where most people get stuck.

As an aside, one of the many time-saving features of Ruby on Mac Ultimate is that it lets you know right away if the version you’re trying to install won’t work on your Mac, and it advises you what to do instead.

It’s understandable that people who are new to Ruby might think that the Ruby version specified by the project is the only version they can use to run the project. Or perhaps they know there’s a newer version they can use, but don’t know how to update the project.

If you’ve been wondering the same thing, I’ll show you step by step how to update the Ruby version in your project. But first, let’s go over why and when you need to upgrade.

Why upgrade the Ruby version in your project?

Every year on December 25, a new version of Ruby gets released with new features and performance improvements. This is when the first or second digit in the version number changes. For example: 2.6, 2.7, 3.0, 3.1, 3.2. In between these main versions, the only changes that get released are bug and security fixes. This is when the third digit changes. For example: 2.7.1, 2.7.2, all the way up to 2.7.8.

When a security issue or bug is discovered and fixed, the fix gets applied to all main versions that are currently supported. The list of supported versions changes over time: old versions reach end of life (EOL) on March 31, three years and three months after their initial release. endoflife.date is a great site for visualizing the support status of a bunch of languages and tools.

For example, if a security fix was released in January 2023, it would be available in 3.2.1, 3.1.4, 3.0.6, and 2.7.8. However, if another one was fixed in April 2023, it would only be available in 3.2.2, 3.1.5, and 3.0.7 because Ruby 2.7.x reaches EOL on March 31, 2023.

This means that if your Ruby project is using a version that has reached EOL, or if the third digit is smaller than the latest version, then your project potentially has a backdoor for malicious people to exploit.

When is a good time to update the Ruby version in your project?

Given what we learned above, there are two situations where updating is a great idea:

  • Whenever a new security/bug fix is released
  • When your project’s Ruby version will reach EOL soon, or has already

Patch releases within a version only contain security and bug fixes, which means they won’t break your project’s code, so it’s perfectly safe to update to the latest release. In the seventeen years I’ve been using Ruby, I don’t remember ever having an issue updating the third digit of a Ruby version.

Even updating the second digit has mostly been painless, such as going from 2.5.x to 2.6.x, or 2.6.x to 2.7.x. The two times to expect breaking changes is when the first digit changes, such as going from 2.x to 3.x, or right after the second digit has changed.

For example, Ruby 3.2.0 was released on December 25, 2022, but you couldn’t generate a new Rails app with it on that day because Nokogiri, one of the gems that Rails depends on, didn’t support Ruby 3.2.0 yet. Nokogiri didn’t add support for Ruby 3.2 until January 12, 2023.

So, if the project you’re trying to run is currently set to 2.7.0, for example, then the first thing you want to do is update it to 2.7.8, which is the latest release in the 2.7.x series. It makes little sense to use a version less than the latest one in a series. You can see the current latest versions on endoflife.date.

Then, once your project is running on 2.7.8, I recommend starting to plan the upgrade to 3.1.4 because 2.7.x reached EOL in March 2023. It will also likely take more time to upgrade due to the breaking changes.

The only time I can think of when you might not be able to update to a new release is if the service you use to deploy your project doesn’t yet support the latest release. Most well-known services, like Heroku, are quick to add support for releases shortly after they come out. If the service you use is slow at updating, I recommend letting them know that having access to security fixes in a timely manner is important to you, or switch to a better service.

How to upgrade the Ruby version in your project

Now that you understand why it’s important to use the latest releases, I’ll show you step by step how to upgrade your project.

Note that if you’re upgrading the Ruby version in a Rails app, and if the new version of Ruby you want to use would require you to update the second digit of your Rails version, then I recommend updating them separately.

For example, if you have an old Rails app using Rails version less than 5.0.5, and Ruby less than 2.7.x, I recommend updating Rails one step at a time, using the official Rails guides, from 3.2.x to 4.0.13, to 4.1.16, to 4.2.11.3, to 5.0.7.2. Then, you can update Ruby to 2.7.8, and then to 3.1.4. That’s because Rails versions less than 5.0.5 require Bundler version less than 2.0, but Ruby 2.7.8 comes with Bundler 2.1.4.

Alternatively, you could try installing an older version of Bundler to be able to update Ruby without updating Rails. For example:

gem install bundler:1.17.3

Once your project is ready to have its Ruby version updated, here are the steps to do it:

  1. First, you need to have a proper Ruby development environment with a version manager, such as asdf, chruby, frum, rbenv, or rvm. If you’re a Ruby on Mac customer, you’re all set with that part. Note that Ruby on Mac Prime only supports chruby, but with Ruby on Mac Ultimate, you can choose your preferred version manager.
  2. Decide which version you want to upgrade to. This should be either 2.6.10, 2.7.8, 3.0.6, 3.1.4, or 3.2.2.

    Then check to see if it’s not already installed. The command you’ll use to check will depend on the version manager you’re using. If you’re a Ruby on Mac customer using the default settings, you can list all installed versions with chruby.

  3. If it’s not already installed, install the version you want to upgrade to. The command you’ll use to install the desired Ruby version will depend on the version manager you’re using. If you’re a Ruby on Mac Prime customer, you’ll run ruby-install followed by the version number. For example:

     ruby-install 2.7.8
    

    However, Ruby versions older than 3.1 are not officially supported in Ruby on Mac Prime.

    If you have Ruby on Mac Ultimate, you’ll use the rom CLI, which installs Ruby almost three times faster than Prime, and faster than any other Ruby version manager. It’s twice as fast as asdf and rbenv, saving you 2 minutes each time you install a version of Ruby. It also automatically uses the best configuration settings for that version. Stay tuned for a comprehensive comparison of all the major version managers, coming soon to this blog.

     rom install ruby 2.7.8
    

    If you need to install Ruby 2.6.10 or older, you’ll either need to use Ruby on Mac Ultimate, or try one of the solutions in my article about installing Ruby 2.6.10 on macOS.

  4. Quit and restart your terminal app.
  5. cd into your project directory
  6. If you track changes with Git, create a new branch:

     git checkout -b upgrade-ruby
    
  7. Open your project in your favorite editor, and find all files that specify the current Ruby version. This will usually be in .ruby-version and/or Gemfile, and possibly other files if you run tests in a CI service like CircleCI or Travis, or if you have a Docker setup.
  8. Replace the current Ruby version with the one you want to upgrade to in all of the necessary files, except Gemfile.lock because it should never be edited manually (unless there are merge conflicts, but that’s a topic for another time).
  9. If you don’t already have a .ruby-version file, you can create it and populate it with your desired Ruby version with one command:

     echo "3.1.4" >> .ruby-version
    
  10. If you already had both .ruby-version and Gemfile, and you had to replace the Ruby version in both files, you can save a step in the future by updating your Gemfile so that it reads the Ruby version from .ruby-version:
     ruby File.read(".ruby-version").strip
    

    If you didn’t already specify the Ruby version in your Gemfile, add the line above at the top of your Gemfile, right before the first gem. Here’s an example of what the first few lines of a Gemfile might look like:

     source "https://rubygems.org"
     git_source(:github) { |repo| "https://github.com/#{repo}.git" }
    
     ruby File.read(".ruby-version").strip
    
     gem "rails", "~> 7.0.4"
    
  11. cd out of your project (for example, by going to your Home folder with cd ~), and back into your project with cd - (a shortcut for going back to the previous directory). This is needed for your version manager to pick up the new Ruby version.
  12. Verify that you are indeed using the new version by checking the current active Ruby version: ruby -v. If not, then switch to it manually. If you’re a Ruby on Mac customer using the default settings, you would run chruby followed by the version number.
  13. Install bundler: gem install bundler
  14. Run bundle install
  15. If you get any errors during bundle install, you might need to update the gems that are causing the errors. You might also need to update the Bundler version in your project:
     bundle update --bundler
    
  16. Run your tests and make sure your project still works.
  17. Once everything looks good, commit the changes in Git if you’re using it, then merge your branch to your main or master branch. If you’re on a team, open a pull request and explain the importance of updating your project’s Ruby version.

I hope this helps!

Since this is such a common source of confusion, I’m planning on adding a feature to Ruby on Mac Ultimate that will analyze your Ruby projects and let you know if there’s a newer version you can upgrade to. And if it’s safe to perform the upgrade, it will automatically run all the steps above for you.

If you still need help after reading this article, you can either buy Ruby on Mac Ultimate, which comes with a free 30-minute consultation, or book a Zoom coaching call with me.