How to upgrade from Rails 5.2 to Rails 6
Last updated on December 20, 2021
Over the last month, I had to upgrade my client's Rails websites to Rails 6. One of the apps was on Rails 5.2 and the other was on an older version - Rails 5.0.6.
I knew that it won't be an easy process, so I decided to document this so hopefully, this will help anyone else who needs to upgrade.
- New tools under your belt - Action text, Action mailbox, testing improvements, multiple databases and more - a lot of new feature that will be useful in the future
- Improves security - several security updates are introduced in Rails 6 - the new Host Authorization middleware and improved security around cookies
- Gem upgrades - Rails is not the only gem that receives new features - in time gems might adopt new features which are dependent on Rails 6
- Makes future upgrades easier - the older your Rails application is, the harder it is to upgrade. Upgrade now, so the future developer (who might be you) doesn't despise you
Rails 6 requires Ruby 2.5 or newer. Depending on when the last time you updated your Ruby version was, this step might be straightforward or you might encounter some errors. The history of Ruby releases might be a helpful reference. I recommend you to start updating at every minor release (the second number in the Ruby version) and inspect if your website is still running as expected at every update.
It didn't take me much time to complete this step. My apps were already at a Ruby version 2.6.2, which was released earlier in 2019, so I just decided to leave it at that. Rails 6 will work perfectly fine at that version, so I can update to the latest Ruby version as a separate task.
Before making the big jump, make sure to upgrade to Rails 5.2.3 and that everything is running as expected at this version.
If your Rails version is 5.2, it would be a painless process. That was the case for one of my apps, but the other app was at Rails 5.0.6. It took me a bit of time to fix several gem dependencies and deprecated methods, but this helped me prepare for the next step.
It's time! Replace your current version of Rails in the Gemfile to
1gem 'rails', '~> 6.0'
and in your terminal:
1bundle update rails
1Bundler could not find compatible versions for gem "activesupport":2In Gemfile:3delayed_job_active_record was resolved to 4.1.3, which depends on4delayed_job (>= 3.0, < 5) was resolved to 4.1.7, which depends on5activesupport (>= 3.0, < 5.3)67jbuilder (~> 2.5) was resolved to 2.9.1, which depends on8activesupport (>= 4.2.0)910kaminari (~> 1.1) was resolved to 1.1.1, which depends on11activesupport (>= 4.1.0)1213lograge (~> 0.11.2) was resolved to 0.11.2, which depends on14activesupport (>= 4)1516rails (~> 6.0) was resolved to 6.0.0, which depends on17activesupport (= 6.0.0)1819rspec-rails (~> 3.5) was resolved to 3.8.2, which depends on20activesupport (>= 3.0)
Rails will output a long list of gems, but in reality we only need to update a small subset of this list.
In this error, this version of the delayed_job_active_record gem is dependent to activesupport with a maximum version < 5.3.
Therefore, we need to upgrade to a version that supports activesupport. We can go to the rubygems website and find a compatible version with active support 6.0. For this gem, version 4.1.4 supports active support 6.0.
Great news! We can just upgrade the Gemfile with this version of the gem and run bundle update rails again.
After this issue was fixed I got another dependency error - this time with the railties gem.
1Bundler could not find compatible versions for gem "railties":2In Gemfile:3devise was resolved to 4.6.2, which depends on4railties (>= 4.1.0, < 6.0)56font-awesome-rails (~> 4.7.0) was resolved to 188.8.131.52, which depends on7railties (>= 3.2, < 6.1)89jquery-rails was resolved to 4.3.5, which depends on10railties (>= 4.2.0)1112fae-rails (~> 2.1) was resolved to 2.1.0, which depends on13jquery-ui-rails (~> 6.0.1) was resolved to 6.0.1, which depends on14railties (>= 3.2.16)1516lograge (~> 0.11.2) was resolved to 0.11.2, which depends on17railties (>= 4)1819money-rails (~> 1.10) was resolved to 1.13.2, which depends on20railties (>= 3.0)2122rails (~> 6.0) was resolved to 6.0.0, which depends on23railties (= 6.0.0)2425rails-ujs was resolved to 0.1.0, which depends on26railties (>= 3.1)2728react-rails (~> 2.4) was resolved to 2.5.0, which depends on29railties (>= 3.2)3031sass-rails (~> 5.0.0) was resolved to 5.0.7, which depends on32railties (>= 4.0.0, < 6)3334web-console (>= 3.3.0) was resolved to 3.7.0, which depends on35railties (>= 5.0)
Did you spot it? We need to bump our devise and sass-rails versions. We do that and once again we run bundle update rails.
But wait. Now we are getting this error?
1fae-rails (~> 2.1) was resolved to 2.1.0, which depends on2devise (~> 4.6.2) was resolved to 4.6.2, which depends on3railties (>= 4.1.0, < 6.0)
In order to use the version of fae-rails which supports Rails 6, I need devise 4.6.2, but devise 4.6.2 doesn't work with railties 6 (which we need for Rails 6). Now what??
If you encounter this problem, go to that gem's Github repo and search for issues or Pull Requests. In the majority of cases, someone else has already done the upgrade.
To fix fae's dependency issue, I went to the Github repo and saw that there is a pull request that bumps the version of Rails, but it was not merged to master as of yet. Some tests were failing as well. The tests looked like were failing because it's an older version of Ruby.
Nevertheless, I will use it by doing the following
1gem "fae-rails", :git => "https://github.com/robikovacs/fae.git", :ref => "2f859885475adf9389c4d80f54d7c60b357625b9"
I need to take this step with caution. Fae and Devise are an important part of the app, so I will make a note of this and look if there has been any merged changes before I deploy to production.
Devise and Fae are popular gems, so I am confident that it will get merged into master in no time.
Continue doing this until you see the green message that indicates that you are finally done with this step
This will help you integrate your rails app with the new config settings. This command will overwrite a lot of your perfectly fine code. That's why I recommend you to select the <mark>m</mark> option to merge the files. Afterwards, select y for every file. Finally, use a merge tool to inspect what changes were implemented.
Using this approach, you will see exactly what is updated by this command so you can decide what you want to keep in and what to replace.
Go to new_framework_defaults_6_0.rb. I suggest to read the comments - there are several new defaults which are recommended to uncomment once you are confident that your app is stable on Rails 6. I did as it was suggested.
The next step is to go to Rails 6 release notes and double-check for any removals and deprecations. If any of them impact your code - fix them!
After you fix your tests and everything is running well locally, push to staging and go around the website to see if something is broken.
I recommend doing this for a couple of days while implementing other features. This should be enough time to find the majority of issues that might have happened during the upgrade.
Level up your web development skills
Get articles, guides and interviews right in your inbox. Join a community of fellow developers.
No spam. Unsubscribe at any time.