How to manage multiple Rails versions

Coming from RVM, many people have problems separating gems (and thus Rails versions) for their applications when switching to rbenv. But this is actually Bundler's job.

This is one of my most popular articles. It was published on May 1st 2014 and received its last update on February 13th 2017. It takes about 3 minutes to read.

It has also been published on Medium. If you like it, please give it some 🖤!

Although a plugin called rbenv-gemset exists (which resembles the functionality of rvm-gemset), rbenv was never intended to manage gems.

While there are certain situations where you want to truly separate gems for different applications, it usually works best to follow this rule of thumb:

Let rbenv take care of managing your Ruby versions and use Bundler for gem management (and therefore Rails versions).

Start with a clean environment

If you think your gems are messed up, you can always uninstall all local gems with the following command:

for i in `gem list --no-versions`; do gem uninstall -aIx $i; done

This will iterate over all installed gems and uninstall them. Don't worry about a few errors — some gems cannot be uninstalled because they are installed by default.

After cleaning up, you need to reinstall Bundler with the command gem install bundler.

We'll create the dummy applications for this article in the /tmp directory, so go there and create a folder with mkdir /tmp/rails-apps.

When you're done with this tutorial, just drop that folder with rm -rf /tmp/rails-apps.

Create an application with the current Rails version

To find out what the most recent Rails version is, use the command gem search rails | grep "^rails ". As I am writing this, it is 5.0.1.

Assuming you have rbenv up and running, create a directory for your application along with a Gemfile to specify your desired Rails version and let Bundler install the dependent gems:

cd /tmp/rails-apps
mkdir my-first-app
cd my-first-app
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'rails', '5.0.1'" >> Gemfile
bundle install

Check that the correct version has been installed using bundle exec rails -v which should output Rails 5.0.1.

Now create your application, let Rails create a new Gemfile (or rather overwrite the existing one by using the --force flag) and instead of installing the bundle (--skip-bundle) update it manually:

bundle exec rails new . --force --skip-bundle
bundle update

A second application with an older Rails version

To create a second application, you basically repeat the steps outlined above. Make another directory for this application, create a Gemfile with the desired Rails version and let Bundler take over (you can list all available versions of the Rails gem with gem list rails --remote --all | grep "^rails "):

cd /tmp/rails-apps
mkdir my-second-app
cd my-second-app
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'rails', '4.2.7.1'" >> Gemfile
bundle install

As bundle exec rails -v will tell you this time, the Rails version for this bundle is 4.2.7.1.

Now create the application:

bundle exec rails new . --force --skip-bundle
bundle update

If you have problems creating the application, check the syntax for the rails command for this specific version (it has not always been rails new …).

Done!

If you look at the output of gem list --local you will see that multiple versions of gems have been installed:

…
rails (5.0.1, 4.2.7.1)
…

This may look messy, but Bundler will take care of choosing the right version for each project. Just make sure that you precede every call to a binary with bundle exec:

bundle exec rails server
bundle exec rails generate model User
bundle exec rake db:migrate
bundle exec rake test
…

Or take a look at Bundler's documentation and search for "binstubs".

Expand your DevOps skills!

Join hundreds of Rails developers and operators on my email list and get my ebook Build Your Own Rails Server as a free welcome gift.

No spam — guaranteed. You can leave at any time.