Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

AS dependencies resolver broken: not missing constant error

#5383
controllers/manage/cars_controller.rb
# encoding: utf-8
class Manage::CarsController < ApplicationController
  def index
    Car.new
  end
end

models/manage/car.rb
# encoding: utf-8
class Manage::Car
end

Using only Car instead of Manage::Car inside the controller make rails fail in production mode with with ArgumentError, Manage is is not missing constant Car! (rails 3rc and master).

A little debugging shows that the following code is executed on each request (but it should only be called once on startup):
Dependencies: called load_missing_constant(Manage::CarsController, :Car)
Dependencies: called load_missing_constant(Manage, :Car)

Reported by gucki · August 15th, 2010 @ 02:23 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Andrew White
    Andrew White
    • State changed from new to invalid
    • Importance changed from to Low

    Whilst this is almost a duplicate of #2283, it is subtly different in that it's more to do with how Ruby searches for constants. If you eliminate Rails from the equation and just do pure Ruby:

    #!/usr/bin/ruby
    
    module Manage; end
    class Manage::Car; end
    
    class Manage::CarsController
      def self.index; Car; end
    end
    
    p Manage::CarsController.index
    

    This script will generate a NameError. However if you nest the class like so:

    #!/usr/bin/ruby
    
    module Manage; end
    class Manage::Car; end
    
    module Manage
      class CarsController
        def self.index; Car; end
      end
    end
    
    p Manage::CarsController.index
    

    This will find the Manage::Car class correctly. Using this and applying it to your situation if you rewrite the controller as follows it will work:

    module Manage  
      class CarsController < ApplicationController
        def index
          Car.new
        end
      end
    end
    

    August 18th, 2010 @ 04:35 PM

  2. gucki
    gucki

    The main problem is that the behavior of rails is different when cache_classes is true/ false.

    The following code should always work:

    require 'rubygems'
    require 'active_support'
    
    module Aa
    end
    
    module Aa::Bb
      def self.lala
        Bb.new
      end
    end
    
    class Bb
      def initialize
        puts "aa"
      end
    end
    
    Aa::Bb.lala
    

    It works, but only when cache_classes is true. When cache_classes is false, the following error occurs:

    Aa is not missing constant Bb!
    

    Doing something similar in a real project, I sometimes also get:

    undefined method `new' for Aa::Bb:Module (NoMethodError)
    

    To reproduce with rails master (3.1.0.beta) just create a new project then create the files [models/aa.rb models/bb.rb models/aa/bb.rb] (contents see above) and put the code "Aa::Bb.lala" in any controller action. Then compare the results with cache_classes set to true/false.

    September 29th, 2010 @ 01:39 AM