There is a bit of background information required to set this article up: I like clean computer systems. In this context, it means only having the required applications or libraries installed. It keeps things simple. To accomplish this in the Ruby world, I have a ~/.bundle/config
that contains BUNDLE_PATH: "vendor/bundle"
. This ensures all gems are placed in the same folder of the application using them, instead of the default of $GEM_HOME
. I only have a handful of gems installed globally, majority being installed per application. One such gem that I previously always had installed globally, including many alternate versions, was Rails. No more!
Recently I have been spending a lot of time experimenting with containerization through Docker. Most of it has been to get an old Rails application (Rails 3.x and Ruby 2.x) running on the latest Apple silicon/ARM architecture powered hardware. During that time I learned a little something to prevent installing Rails globally, and instead only within the context of the application.
Create the folder to store your application’s source code, along with the Gemfile
.
mkdir MyApp
cd MyApp
touch Gemfile
touch Gemfile.lock
Edit the Gemfile
to include the source and Rails.
source 'https://rubygems.org'
gem 'rails', '~>6'
Install the gems.
bundle install
Finally, initialize the Rails project. This will use the local version of Rails that was specified in the Gemfile
and now installed to MyApp/vendor/bundle
. The --force
will overwrite the current Gemfile
and Gemfile.lock
without a prompt. The name of the application will be the same as the folder.
bundle exec rails new . --force
That’s it! A gem list
will show your global gems, of which Rails is nowhere to be seen. A bundle list
will show all of the gems installed for MyApp
, including Rails.
Why though? It’s a bit cleaner, I like it.