views:

16

answers:

1

Bundler is breaking my resourceful route!

To confirm I created a clean rails app (2.3.4) and made a users scaffold.

map.resources :users creates the following:

    users GET    /users(.:format)                   {:controller=>"users", :action=>"index"}
          POST   /users(.:format)                   {:controller=>"users", :action=>"create"}
 new_user GET    /users/new(.:format)               {:controller=>"users", :action=>"new"}
edit_user GET    /users/:id/edit(.:format)          {:controller=>"users", :action=>"edit"}
     user GET    /users/:id(.:format)               {:controller=>"users", :action=>"show"}
          PUT    /users/:id(.:format)               {:controller=>"users", :action=>"update"}
          DELETE /users/:id(.:format)               {:controller=>"users", :action=>"destroy"}

Now I followed the instructions at http://gembundler.com/rails23.html and all of the sudden my routes broke:

    users GET /users(.:format)                   {:action=>"index", :controller=>"users"}
          GET /users(.:format)                   {:action=>"index", :controller=>"users"}
 new_user GET /users/new(.:format)               {:action=>"index", :controller=>"users"}
edit_user GET /users/:id/edit(.:format)          {:action=>"index", :controller=>"users"}
     user GET /users/:id(.:format)               {:action=>"index", :controller=>"users"}
          GET /users/:id(.:format)               {:action=>"index", :controller=>"users"}
          GET /users/:id(.:format)               {:action=>"index", :controller=>"users"}

Inserting and removing the code block from config/boot.rb breaks and fixes, respectively, my routes! Anyone have any ideas??

This is gonna be long... boot.rb:

# Don't change this file!
# Configure your app in config/environment.rb and config/environments/*.rb

RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)

module Rails
  class << self
    def boot!
      unless booted?
        preinitialize
        pick_boot.run
      end
    end

    def booted?
      defined? Rails::Initializer
    end

    def pick_boot
      (vendor_rails? ? VendorBoot : GemBoot).new
    end

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

    def preinitialize
      load(preinitializer_path) if File.exist?(preinitializer_path)
    end

    def preinitializer_path
      "#{RAILS_ROOT}/config/preinitializer.rb"
    end
  end

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

  class VendorBoot < Boot
    def load_initializer
      require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
      Rails::Initializer.run(:install_gem_spec_stubs)
      Rails::GemDependency.add_frozen_gem_path
    end
  end

  class GemBoot < Boot
    def load_initializer
      self.class.load_rubygems
      load_rails_gem
      require 'initializer'
    end

    def load_rails_gem
      if version = self.class.gem_version
        gem 'rails', version
      else
        gem 'rails'
      end
    rescue Gem::LoadError => load_error
      $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
      exit 1
    end

    class << self
      def rubygems_version
        Gem::RubyGemsVersion rescue nil
      end

      def gem_version
        if defined? RAILS_GEM_VERSION
          RAILS_GEM_VERSION
        elsif ENV.include?('RAILS_GEM_VERSION')
          ENV['RAILS_GEM_VERSION']
        else
          parse_gem_version(read_environment_rb)
        end
      end

      def load_rubygems
        min_version = '1.3.2'
        require 'rubygems'
        unless rubygems_version >= min_version
          $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
          exit 1
        end

      rescue LoadError
        $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
        exit 1
      end

      def parse_gem_version(text)
        $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
      end

      private
        def read_environment_rb
          File.read("#{RAILS_ROOT}/config/environment.rb")
        end
    end
  end
end

class Rails::Boot
  def run
    load_initializer

    Rails::Initializer.class_eval do
      def load_gems
        @bundler_loaded ||= Bundler.require :default, Rails.env
      end
    end

    Rails::Initializer.run(:set_load_path)
  end
end

# All that for this:
Rails.boot!

preinitializer.rb

begin
  require "rubygems"
  require "bundler"
rescue LoadError
  raise "Could not load the bundler gem. Install it with `gem install bundler`."
end

if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24")
  raise RuntimeError, "Your bundler version is too old for Rails 2.3." +
   "Run `gem install bundler` to upgrade."
end

begin
  # Set up load paths for all bundled gems
  ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
  Bundler.setup
rescue Bundler::GemNotFound
  raise RuntimeError, "Bundler couldn't find some gems." +
    "Did you run `bundle install`?"
end

Gemfile

source "http://rubygems.org"
source "http://gemcutter.org"

gem "rails", "2.3.4"
gem "newrelic_rpm"
gem "authlogic"
gem "geokit"
gem "will_paginate"
gem "paperclip"
gem "delayed_job"
gem "delayed_paperclip"
gem "activemerchant", :require => "active_merchant"
gem "aws-s3", :require => "aws/s3"
gem "acts_as_archive"
gem "carmen"
gem "super_exception_notifier", :require => "exception_notification"
gem "bitly"
gem "thinking-sphinx", :require => "thinking_sphinx"
gem "ts-delayed-delta", :require => "thinking_sphinx/deltas/delayed_delta"
gem "deep_merge"
gem "acts_as_taggable_on_steroids"
gem "whenever"
gem "ar-extensions"
gem "fastercsv"

routes.rb

ActionController::Routing::Routes.draw do |map|
  map.resources :users

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end
A: 

deep_merge is the gem that is causing the problem. bundler itself works fine without it.

Jaime Bellmyer
whoa! you're right!!! hmmmmmmm.... any ideas why that would be??
Steven Ou
the deep_merge and deep_merge! hash methods exist already, and they're overwritten with this gem. That makes sense, because when the gem is used, your route hashes are re-ordered. `rake routes` normally shows the controller first, then action, but deep_merge flipped that. Anyway, are you sure you need it? Something in routing is using deep_merge and expecting the rails default version. The gem is breaking what rails expects.
Jaime Bellmyer
ahhhhh that explains it all... to be honest i wasn't aware that rails already had deep_merge functions. so then i'm actually not sure that i need the gem. (although i also can't think of why the gem would be created if the methods already exist...). i'll have to try out the default deep_merge methods and see if they work for what i need! thanks a LOT! i don't think i would've ever solved this one by myself :) gotta love SO!
Steven Ou