I’ve written here before about my love affair with Isolate. Isolate is a beautifully simple tool for installing RubyGems in a sandbox. I really enjoy not having to think about conflicting installed versions of gems, or infecting my system with gems that I won’t ever use. I use it on every single project I touch, whether it’s used upstream or not, and it rarely takes longer than a few minutes to move an existing project to it. It’s even possible to use Isolate to wrap other RubyGems sandboxes, such as Bundler, in its warm embrace.
A RubyGems install on any one of my machines looks like this:
srbaker@gobo:~$ sudo gem list *** LOCAL GEMS *** isolate (3.0.0)
Setting up a Rails 3 project skeleton requires the rails gem to be installed, and then requires you to invoke an executable included in that gem. The solution for bootstrapping a Rails 3 project without installing the gem system-wide is not immediately obvious to many people, so I’ve decided to document the process here. Isolate has a terrific feature that allows you to invoke shell commands inside the isolated environment by using a rake task, you just need to get Rails installed in that environment.
To start, I create a new directory for my Rails project. In the new directory I create my Isolate file, which has one line:
gem 'rails', '3.0.3'
Next we need a rakefile which will load Isolate and sandbox the Rails 3 gems. I call this file ‘bootstrap’, since Rails will generate a Rakefile. The ‘bootstrap’ rakefile looks like this:
require 'rubygems' require 'isolate/now' require 'isolate/rake'
If you have the Rails 3 gems install, a new project is created by using the ‘rails new’ command. Since we have a bootstrap rakefile created which will sandbox Rails 3, we can create the Rails sandbox, and our new project with the following command:
$ rake -f bootstrap isolate:sh['rails new . --skip-gemfile']
When this command has run, Isolate will install Rails 3 and its dependencies, and then run the command ‘rails new . –skip-gemfile’. You will have a new Rails 3 project in your current directory. The next thing you should do is add a reference to the gem(s) that support your chosen database engine. I usually run sqlite3 locally, so I add gem ‘sqlite3-ruby’ to my Isolate file. You may also want to use ‘pg’. (You might be forced to use ‘mysql’, but you should never do this by conscious decision.)
Since Rails depends on Bundler out of the box, we need to get rid of this dependency before continuing. It will still continue to be installed in the sandbox, since there is a gem dependency on it, but we don’t want our application using it. To do this, edit config/boot.rb and remove all of the lines that load Bundler; on Rails 3.0.3, remove the following lines:
# Set up gems listed in the Gemfile. gemfile = File.expand_path('../../Gemfile', __FILE__) begin ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setup rescue Bundler::GemNotFound => e STDERR.puts e.message STDERR.puts "Try running `bundle install`." exit! end if File.exist?(gemfile)
Load Isolate instead, by replacing those lines with these:
require 'isolate/now' require 'isolate/rake'
(You may want to put the isolate/rake requirement in your Rakefile.) You should also remove the call to Bundler.require in config/application.rb as well.