Uninitialized Constant MERB_ROOT Error

I intend to write articles covering actual programming soon, as opposed to the hodge-podge, link-filled, advocacy-style articles I have written up to now. In spite of that, I hope that the couple short blurbs about Rails or Merb errors do help a person or two. These little things can be frustrating as hell.

Where Did This Error Come From?

If you have gotten this error, you are probably using Haml and Sass in your Merb application, right? You installed Haml, wrote a few views with it, and then decided to move on and generate the next controller or model, right? Right. This is probably what it looks like:

>script/generate controller sessions

Connecting to database...

/usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:266:in `load_missing_constant': uninitialized constant MERB_ROOT (NameError)
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:453:in `const_missing'

        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:465:in `const_missing_before_generators'
        from /usr/lib/ruby/gems/1.8/gems/rubigen-1.1.1/lib/rubigen/lookup.rb:13:in `const_missing'

        from /usr/lib/ruby/gems/1.8/gems/haml-1.8.0/lib/sass/plugin/merb.rb:13
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'

        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:496:in `require'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:342:in `new_constants_in'

         ... 23 levels...
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:496:in `require'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:342:in `new_constants_in'

        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
active_support/dependencies.rb
:496:in `require'
        from script/generate:12

Crap. What do I do?

Ardekantur knows what to do. His blurb on the subject is what helped me. I ended up opening the Sass' Merb plugin file in Vim, and replacing it all with the trunk version.

Open the file.

sudo vim /usr/lib/ruby/gems/1.8/gems/haml-1.8.0/lib/sass/plugin/merb.rb

It should look like this:

  unless defined?(Sass::MERB_LOADED)
    Sass::MERB_LOADED = true

    Sass::Plugin.options.merge!(:template_location  => MERB_ROOT + '/public/stylesheet
  s/sass',
                                :css_location       => MERB_ROOT + '/public/stylesheet
  s',
                                :always_check       => MERB_ENV != "production",
                                :full_exception     => MERB_ENV != "production")
    config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {}
    config.symbolize_keys!
    Sass::Plugin.options.merge!(config)
 
    class MerbHandler # :nodoc:
      def process_with_sass(request, response)
        Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sas
  s::Plugin.options[:always_check]
        process_without_sass(request, response)
      end
      alias_method :process_without_sass, :process
      alias_method :process, :process_with_sass
    end
  end

Uh, go ahead and delete all that. Yeah, delete it all. Paste this in there:

unless defined?(Sass::MERB_LOADED)
  Sass::MERB_LOADED = true

  version = Merb::VERSION.split('.').map { |n| n.to_i }
  if version[0] <= 0 && version[1] < 5
    root = MERB_ROOT
    env  = MERB_ENV
  else
    root = Merb.root
    env  = Merb.environment
  end

  Sass::Plugin.options.merge!(:template_location  => root + '/public/stylesheets/sass',
                              :css_location       => root + '/public/stylesheets',
                              :always_check       => env != "production",
                              :full_exception     => env != "production")
  config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {}
  config.symbolize_keys!
  Sass::Plugin.options.merge!(config)

  class MerbHandler # :nodoc:
    def process_with_sass(request, response)
      Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
      process_without_sass(request, response)
    end
    alias_method :process_without_sass, :process
    alias_method :process, :process_with_sass
  end
end

Save that. Then try your script/generate line again. It should work now.

Wait, Don't Go Yet!

Really, Ardekantur did all the work. I sort of feel like I plagiarized this whole article. You should go ahead and check out his blog. In particular, he has written an article Writing A Web Application In Merb, Part I, in which he exudes a test-first attitude, and uses RSpec, both of which are a Good Thing. I think I'm going to subscribe in anticipation of the next part (I assume II, or maybe J). You should at least take a look!