Whenever a Ruby on Rails developer hears the phrase “New Rails update!” they will no doubt experience a mixture of excitement and fear. It’s always very exciting to see the new tools that come with a new Rails version and all the new possibilities that go with it. But at the same time, you know that you are bound to have some hiccups with some legacy code or some old gem that you use on your application. Nevertheless, I decided it was time to upgrade our Rails app.
Needless to say, we will be following the guides from guides.rubyonrails.org on how to upgrade from Rails 5.2 to 6.0.
Before updating anything on your app, make sure that you have a good amount of tests! In our case, our test coverage is decent and we also have a good system for tracking bugs, so even if all of our tests pass we still know if a new bug shows up.
Just like any other gem update, I opened my Gemfile, changed the Rails version
'Rails', '~> 6.0.0' and ran
bundle update Rails.
As expected, I got loads of
"Bundler could not find compatible versions for gem" errors, but luckily I only had to update two gems manually and many other gems were updated automatically. And done! Now we were ready to upgrade to Rails 6.0… or were we?
You can’t say you’ve successfully upgraded Rails if your application doesn’t work anymore. So we have to ensure the functionality is the same as it was before, and what better option do we have to check than testing?
After running our automated tests we had multiple tests failing and lots of deprecation warnings. Most of the deprecations and errors were very straightforward to fix – for example,
update_attributes had to be changed to
update, and the
case_sensitive default value for
presence validations was going to change, so it had to be specified, etc. But, after fixing all the failing tests, we finally had our Rails app upgraded! …well, not quite.
Revisiting the Rails guides
It’s always a good idea to revisit the guides and check you haven’t missed anything. In my case I had missed two updates.
The first one was the
force_ssl option, which enforces
https. Previously, it could be configured in the controllers, but this has been removed in Rails 6.1. In our application we were turning it off on a couple of actions, and after some investigation I realised that we should keep it on at all times and move the configuration into the production and staging environment configuration files.
The other one was the cookie encryption change. In Rails 6.0, the purpose and expiry metadata are embedded into the cookie to make it more secure, but this change is not compatible with older versions of Rails. Since we were not sure if we would have to rollback the change, I followed the guide recommendation and set
Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = false
until we were sure that we were sticking with Rails 6.0.
Another new addition caught my attention – the Zeitweirk autoloading. I tried adding it into our application but failed miserably. That is because we are using a very old gem that does not follow the right file naming convention, so for now we are still using the classic Rails autoloading.
Even though we are not yet using all that Rails 6.0 has to offer, I am satisfied with the upgrade and think we have made the right decision.
Finally, it was time to create the PR, check all the tests were passing, and get the approval of the other developers.
The PR was merged, and our app is now finally upgraded to Rails 6.0!