Skip to content

Instantly share code, notes, and snippets.

@mediafinger
Created September 23, 2022 16:43
Show Gist options
  • Save mediafinger/0ed4c51a121a490b5cd7aa89a8e05843 to your computer and use it in GitHub Desktop.
Save mediafinger/0ed4c51a121a490b5cd7aa89a8e05843 to your computer and use it in GitHub Desktop.
Updating Ruby on Rails apps

How to Update a Ruby on Rails app

To safely update the Ruby and Rails version, your app should have a proper test suite you can rely on. But even with a great test suite, I always recommend running a rake task, starting the rails console and starting the rails server and using your app in the browser, before opening a PR and asking for reviews.

Ruby updates

Do it incrementally, don't skip any minor versions.

Which means, if your app is still on Ruby 2.7.x, then first update to the latest 2.7.X version, before updating to the latest 3.0.Y version and only when this has been done successfully, upgrade to the latest 3.1.Z version.

Ideally you fix all deprecation warnings before switching to the next higher version.

Ruby has good documentation about the changes from version to version:

Though you might end up googling or checking StackOverflow for specific refactorings anyway.

Doing updates incrementally also means deploying them to staging and production and only updating to the next version when no issues occured.

Ensure you update the Ruby version everywhere:

  • .ruby-version file
  • Gemfile (optional, not all Gemfiles include it)
  • deployment scripts
  • CI workflows
  • .rubocop.yml

Ruby versions

Before you install a new Ruby version (I use ruby-install to install new versions and chruby to switch Ruby versions) you should update your system to ensure it has the latest compilers and libraries available. On my Mac I would run brew update && brew upgrade before I begin.

Rails updates

Do it incrementally, don't skip any minor versions.

Same as with Ruby, and also Rails has a really good officia upgrade guide you can follow - just repeat all the steps for every new version:

There are also really good unofficial guides out there to teach you about necessary refactoring steps, like:

Rails versions

Gem / Dependency updates

To be able to use newer versions of Ruby and Rails often means you have to update - or even replace - some of the gems you use. Before you start any other updates, you should ensure your dependencies are on the most recent version available.

Gemfile ~> version limitations

First set the allowed versions for all your gems in the Gemfile with the squiggly operator. e.g. instead of just declaring:

  • gem "devise" set gem "devise", "~> 4.7"
  • which behaves the same as gem "devise", ">= 4.7, < 5.0".

I always recommend to use ~> MAJOR.MINOR as this proofed to be flexible enough for regular gem updates while limiting the version upgrades to (most-likely) non-breaking changes. At least when the gem authors properly follow Semantic Versioning (SemVer).

To find out which version your app is using and therefore which limit you should set, check Gemfile.lock.

Don't declare ~> MAJOR.MINOR.PATCH version, as this limits updates too much and you could just set the fixed version, when you are afraid of updates of this gem.

Some gems where patch level updates are known to cause issues, I set to a fixed version, in particular this one:

  • gem "rails", "7.0.4" which behaves the same way as gem "rails", "= 7.0.4"

Other gems which are very stable, you might allow to update freely, by either not declaring any version limitation or an open ended one, like: ">= 1.10", but I would generally advise against this.

Detect outdated gem versions

Theoretically you could run bundle update and update all the gems - at least to the maximum versions you declare in the step above. When you have not done this in a long time, it will lead to too many changes though, which will make it hard to determine which update might lead to issues.

So instead run bundle outdated to get an impression which gems have newer version and then run bundle update gem_name another_gem_name to update the gems in smaller groups. After every update check the parts of the application that might have changed and run the whole test suite.

The bundle outdated output will also show you versions which you can only update to after you changed the version limitation in the Gemfile. Now that this is a dedicated, deliberate step, you are aware when you update a gem to a version that has potentially breaking changes and you will put the extra effort in to ensure the update didn't break current behavior.

Often those newer gem versions only work on newer versions of Ruby or Rails - which means during the update of the whole application you will jump between updating dependencies, updating Ruby and updating Rails, if you are updating multiple versions of Ruby or Rails at once.

After you've reached the latest Ruby and Rails version (or the ones you were aiming for) I'd recommend to update in the next step all the gems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment