When to Specify a Gem Version for Ruby on Rails Applications
If you develop with Ruby on Rails, or are learning to, you may at some point have had some questions about gem versions. Sometimes it can be confusing which gem version to choose, whether or not to explicitly state a version number, and how to do it. In order to clear things up a bit, we are going to cover some of the basics regarding the different ways to specify a gem version, the difference between the Gemfile and the Gemfile.lock, and how the bundle install command works to update the gems in your application.
When you are building a Ruby on Rails application, you are likely using Bundler to manage your gems in a Gemfile. If you’ve ever looked online for help with gem installation or versions, you may have noticed that sometimes gems are simply added to the Gemfile by typing gem and the name of the gem in parenthesis, and sometimes there are versions with various symbols (e.g., ‘>= 2.3.0’) like you see below.
But when should you just put in the Gemfile name, and when is it best to specify a version? Well, generally an exact version is explicitly used when you know (or read) that a specific version has already been tested and works with application features or specifications that you are using. For example, if you are pushing your application to a cloud application platform, there may be issues with certain gem versions working correctly on that platform. If you experienced problems yourself using a particular gem, or know that other developers have, you may want to look into what versions of that gem are known to be stable for your specifications. By adding the exact version to your gem (e.g., ‘= 2.1.6’) in the Gemfile, you are assuring that only that specific stable version is used.
Similarly, you may find out only newer (or older) versions of a gem work with your application’s specifications. For example, a new version of a gem comes out and the changes allow that gem to now work in your application, but you know that the previous versions didn’t. Or vice versa, a new update to a gem may not be supported on your cloud platform for example, or may require broader changes in your application that you are not planning to undertake. In these cases it may be beneficial to explicitly set the gem version to greater (or lesser) than or equal to (‘>=’, ‘<=’) a specific gem version.
Sometimes you will also see use of the tilde and greater than sign (‘~>’), which looks a bit like an arrow (pictured below). This indicates that only the last integer in the version number can increase.
So in this example, the bootstrap-sass gem can increase as long as it is still a 3.3.5.xx version. In other words, it could update to 18.104.22.168, or all the way up to 22.214.171.124, but it can never be 126.96.36.199.
Gemfile vs. Gemfile.lock
To better understand when to use the above options for specifying a version, we need to understand how the Bundler works. After adding your gem(s) to the Gemfile (or making changes to the Gemfile), you need to run the bundle install command.
This will use the current saved version of the Gemfile to install (or reinstall) your gems, based on whether you specified gem versions and parameters. If you did not specify the exact version, or the parameters for acceptable versions (e.g., ‘<’, ‘>=’), the Bundler will generally try to install the latest version. Note that this is not always the case and if you did not tell it the exact version, you may or may not get the absolute latest version of the gem.
When you run bundle install, the Bundler will fetch all remote sources, resolve dependencies (which we won’t go into here), and either create or update the Gemfile.lock file. This file displays all of the gem versions and dependencies that were installed and updated after you last ran bundle install. In other words, the Gemfile.lock file is where you can check the gem versions that are installed for your application, unless changes are made to the Gemfile and bundle install is run again.
One thing to keep in mind is if you add or change any gem in the Gemfile, running bundle install to implement that specific change may inadvertently update/change the version for any of the other gems in your Gemfile where the exact version is not explicitly stated (e.g., if a new version was released since you last ran bundle install). Thus it is good practice to test the functionality of your application every time you run bundle install , to make sure any unintended gem updates haven’t adversely impacted your application.
About the Author
I'm a clinical psychologist, informaticist, developer, crypto-enthusiast, and incurable tech junkie.