Freezing Your Rails App and Unpacking Gems

Rails is constantly evolving. Although each new version of Rails is (usually) an improvement on the last, upgrading to the latest version can sometimes lead to annoying problems with your existing apps. For example, when upgrading to Rails 2.3.2, you may have found your earlier apps raise exceptions due to application.rb being re-named to application_controller.rb.

If you’re running your app on a shared server, you may not have the luxury of choosing which version of Rails is installed on your host’s machines. Imagine building an app using all the latest features from Rails 2.2 only to find out that your host have Rails 2.1 installed :S

The easy way around this is to ‘freeze’ Rails to your /vendor folder. Simply put, this means copying the core Rails gems into your apps vendor directory and loading this version of Rails.

Whenever you start your rails app, one of the first things to happen is that boot.rb is loaded (config/boot.rb). If you have a look in this file you should see a method called pick_boot which determines which version of rails to load.

# in /config/boot.rb
def pick_boot
  (vendor_rails? ? VendorBoot : GemBoot).new
end

def vendor_rails?
  File.exist?("#{RAILS_ROOT}/vendor/rails")
end

The first place it looks is in vendor/rails/, if there are Rails gems here, these will be loaded in place of Rails gems installed on your system. This is where we need to store our ‘frozen’ version of Rails.

To ‘freeze’ your rails gems, simply type the following in your terminal window:

rake rails:freeze:gems

This will create a new folder in /vendor/ called ‘rails’ and unpack all of the core Rails gems. The version will depend on which version you are running on your system at the time.

You now have your very own frozen version of Rails.

To freeze to the latest version or ‘edge’ Rails, use this command:

rake rails:freeze:edge

This is a great way to try out some of the new features in the latest release without disturbing your other applications.

If you’d like to freeze to a particular version of Rails, say release 2.1.1, you can do so by specifying the RELEASE like so:

rake rails:freeze:edge RELEASE=2.1.1

As well as freezing the default Rails gems you can also freeze any other gems your application requires. This is really handy, particularly if you need to move your app from computer to computer. Instead of having to install the required gems wherever your app goes, your app can pack the gems up and take them with it.

To unpack the required gems simply run

rake gems:unpack:dependencies

This will unpack all of the gems required in your environment.rb file plus any gems they may require into vendor/gems/

note – you could also use rake gems:unpack, but this only unpacks those gems you’ve explicitly specified in environment.rb. These gems may not work properly without their dependencies so it’s worthwhile unpacking them too.

If you decide to unfreeze Rails and revert back to the system installed version instead, simply run:

rake rails:unfreeze

This will remove the rails directory from /vendor/ and all of its contents. As far as I’m aware, you still have to remove any unpacked gems manually.

Written by

Photo of Gavin Morrice
Gavin Morrice

Software engineer based in Scotland

Connect with me