This project is archived and is in readonly mode.

#5383 ✓invalid
gucki

AS dependencies resolver broken: not missing constant error

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

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)

Comments and changes to this ticket

  • Andrew White

    Andrew White August 18th, 2010 @ 04:35 PM

    • 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
    
  • gucki

    gucki September 29th, 2010 @ 01:39 AM

    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.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

People watching this ticket

Referenced by

Pages