How to upgrade Rails
I don’t write much about Rails here but whoa, two posts in a row! Well, it turns out that I thought I should record another lesson I learned while upgrading Rails: how to do it, meaning, what are the practical steps one should take to upgrade Rails?
During my research at work I came across many resources, including Rails’ own upgrade guide, but after running three upgrades, I think I got my own process. And here is the key take-away: this is what worked for ME. There might be many issues with this process - don’t DM me! - but if in the future I need to run another upgrade, I will consult this notes (yeah, take this as my field notes! There!)
The main issue to be resolved: dependencies
The Rails version on a project can only be upgraded after all dependencies are properly resolved. At work we use bundler as a gem manager, so all information below takes that into account.
There are two approaches for dealing with dependency management: one approach is to go through the Gemfile and check and update all installed gems. This might take quite some time depending on how many gems the project has but it’s also a very conservative approach. If this is your first time upgrading, do this!
The other approach is to try to update the Rails gem version in the Gemfile to start with and run bundle update rails
. This will most likely throw an error similar to the one below. The next step is to identify which gems are preventing the project to be upgraded.
Note that this second approach fails the upgrade process, which means that the rails version is still the old one. It can also be tricky to identify which gem is holding the upgrade back: most times the error messages are not very clear and dependencies might depend on yet another dependency, making it even harder to find the start point. Another problem with this approach is that at the end, only the required gems will have been upgraded, when in an ideal scenario, projects are always up to date with dependencies.
Typical dependency error message when attempting to upgrade Rails:
Bundler could not find compatible versions for gem "activemodel":
In Gemfile:
rails (~> 4.0.13) was resolved to 4.0.13, which depends on
activerecord (= 4.0.13) was resolved to 4.0.13, which depends on
activemodel (= 4.0.13)
draper (~> 1.0) was resolved to 1.4.0, which depends on
activemodel (>= 3.0)
simple_form (~> 3.1.1) was resolved to 3.1.1, which depends on
activemodel (~> 4.0)
The best way, in my opinion, to deal with an error similar to the one above is to check each dependency (gem) listed in the error message for a version conflict. One gem might need to be upgraded to resolve all other dependencies. Note that all active*, action*, etc are Rails related and there’s no way to upgrade those apart from Rails itself.
Yeah, it’s tricky to find which gem is throwing the error. No easy way out of that… ¯\(ツ)/¯
Despite all the cons, on my last two upgrades I used this second approach.
More on updating gems
Before updating a gem, you need to check it for compatibility issues: the latest gem version might not be compatible with your Rails target version. In this case, aim to have the latest possible version you can.
Here’s an outline of what you should look for when trying to upgrade gems:
- Check the gem version installed: in the app, run
gem list <gen_name_here>
. This will show all versions of the gem installed in the app. If there’s more than one, another good place to check is theGemfile.lock
- Go to RubyGems.org and search for the installed gem. Here you can see the latest gem version and lots of information about that gem
- Go to the source code for the gem and look for a
CHANGELOG.md
or similar file (VERSIONS, CHANGES, HISTORY, NEWS, etc). Check if there are any breaking changes between your currently installed version and the latest and also if there is any compatibility issues with your Rails target version in any of the gem’s version. It might be the case that you can’t update the gem to latest because it doesn’t work with your Rails target version. - If there is no changelog type information, check the file
<gen_name>.gemspec
in the root of the source code. That file shows any gem dependencies, if any - If no information is found in the source code, try Googling
<gem_name> rails <your_target_version> support
- If there is any issues preventing the gem to be updated to latest, make sure you specify the desired version in the
Gemfile
. It’s a good idea to use a conservative indicator here (~> 3.5.0
, for example).
How to update a gem
-
In the app, run
bundle update <gem_name>
. In most cases this should update the gem to the desired version: there will be a nice message highlighting the change- If the gem version doesn’t change, look for possible dependencies or requirements (for example, some gems will only work with the Rails target version. In this case, the gems must updated at the same time as the Rails version, by passing the gem name along with
rails
to the bundle update command).
- If the gem version doesn’t change, look for possible dependencies or requirements (for example, some gems will only work with the Rails target version. In this case, the gems must updated at the same time as the Rails version, by passing the gem name along with
-
Restart your server (again, this can vary, but I have puma, so:
pumactl restart
) so the new gem version gets implemented -
Load the app and do a quick check
-
It’s a good idea to commit each gem update separately, so you can roll back if any issues are identified
Updating the Rails version
After all dependencies are updated as required, you can update Rails itself and any gem that needs to be updated at the same time.
- Change the Rails version in the
Gemfile
to the target version - Run
bundle update rails
- If everything goes well, there should be a list of gems updated. If you check the rails version (
rails --version
), it will show the new version - Restart the server
- If this fails, the error message will list the dependency issues, which means that one or more gems are not running the required version yet and the upgrade process will have failed.
Afterwards, run the full test suite to make sure all tests pass. Warning: some (or many!) will probably fail.
Did this help you? Let me know on X!
The post How to upgrade Rails was originally published at flaviabastos.ca