Using the new Rails 3.0 Gem bundler with Passenger, Mongrel and Heroku

UPDATE 19th Feb 2010: Bundler is moving pretty fast! For the most up to date information I’d checkout http://github.com/carlhuda/bundler and specifically this gist (http://gist.github.com/302406) to find out the latest!

Recently we were unsure whether we would be deploying a site to our own hosted system or heroku. I love heroku but there are times when it just doesnt suit the project and a bit more fine grained control is nessesary.

In order to use heroku it was suggested that you move over to the new gem bundler that Yahuda has been working on as part of rails 3.0. However it seems there are a couple of different ways to get the bundler running. The default recomended way works great for mongrel and heroku but didn’t play so nice with passenger.

The default is to place all of the following code into config/preinitializer.rb:

require "#{File.dirname(__FILE__)}/../vendor/bundler_gems/environment"

class Rails::Boot
  def run
    load_initializer
    extend_environment
    Rails::Initializer.run(:set_load_path)
  end

  def extend_environment
    Rails::Initializer.class_eval do
      old_load = instance_method(:load_environment)
      define_method(:load_environment) do
        Bundler.require_env RAILS_ENV
        old_load.bind(self).call
      end
    end
  end
end

After a bit of searching around it seems that in some spawn methods this does not work great with passenger.

The solution

Instead use the following:

In your config/preinitializer.rb just include this part

require "#{File.dirname(__FILE__)}/../vendor/bundler_gems/environment"

Then in config/boot.rb place this just before the last Rails.boot! line like so:

# for bundler
class Rails::Boot
  def run
    load_initializer
    extend_environment
    Rails::Initializer.run(:set_load_path)
  end

  def extend_environment
    Rails::Initializer.class_eval do
      old_load = instance_method(:load_environment)
      define_method(:load_environment) do
        Bundler.require_env RAILS_ENV
        old_load.bind(self).call
      end
    end
  end
end

# All that for this:
Rails.boot!

That should allow you to easily boot from either server and works great with heroku.

Thanks to Mathew Todd for giving the solution based upon gem cutters commit here.

Advertisements

About Steve Smith
Software developer (often ruby, rails but I enjoy loads of languages), semantic tech. fanboy, skydiver, all round geek. Owner of dynamic:edge (hire us) the makers of CloudMailin.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: