Autoload path and STI inheritance issue in Rails 2.3.9

I have two models: User and Manager. I use STI to inherit `Manager`
from `User` model.


class User < ActiveRecord::Base


class Manager < User

I have added the models in the custom directory to load path as


config.autoload_path += File.join(RAILS_ROOT, "custom_lib", "models")

Every thing works as expected in development mode. In the production
mode I get the following error:

The single-table inheritance mechanism failed to locate the subclass:

For some reason rails is not loading the inherited classes.

To work around this issue I explicitly require the classes in an


Dir[File.join(RAILS_ROOT, "custom_lib", "models", "*.rb")].each do |
  require(File.join(File.dirname(file_name), File.basename(file_name,

I prefer to use autoload_path. I am wondering if anybody can explain
the reason for this behavior and any possible fix.

I am on Ruby 1.8.7, Rails 2.3.9, Ubuntu

The option is called "autoload_paths", guess the singular is a typo in
the mail right?

In that case, please try to reproduce it in a minimal application,
file a ticket with it, and assign it to me.

It is a typo, I am using autoload_paths.

I will file a bug after reproducing it in a simpler setup


Does it work if you add your path to eager_load_paths as well as autoload_paths? e.g:

  config.eager_load_paths << File.join(RAILS_ROOT, "custom_lib", "models")

It looks as though extra autoload_paths don't get added to eager_load_paths by default and autoloading is turned off when cache_classes is true.

Indeed autoloading is on in any environment, that is, the
const_missing hook is always there.

fxn@halmos:~/tmp/test-autoloading ∵ cat config/application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
module TestAutoloading
  class Application < Rails::Application
    config.autoload_paths += %W(#{config.root}/lib)

fxn@halmos:~/tmp/test-autoloading ∵ cat lib/foo.rb
module Foo
  p Rails.env

fxn@halmos:~/tmp/test-autoloading ∵ rails runner -e production Foo

I've seen this confusion several times. Let me explain.

In production we eager load from a few places. Reason is
thread-safety, and it is also COW-friendly for multi-process.

Now, since Rails eager loads model/user.rb, the User constant won't
trigger const_missing in production. But const_missing is still there,
and custom directories added to autoload_paths get autoloading just

Yes, you're right - I was under the impression that it was turned off in production since require and autoload are inherently unsafe in threaded applications.