app/models, app/controllers, ... not always in load_paths #4262

Closed
lfarcy opened this Issue Jan 2, 2012 · 7 comments

6 participants

@lfarcy

While transitioning a Rails app from 2.3.5 to 3.0.11, I stumbled upon an unexpected situation where Rails.root/app/models, Rails.root/app/controllers, ... were no more in $LOAD_PATHS.

After searching a bit and comparing Rails 2.3.5 and 3.0.11 codebase, I realized this was due to the way we use config.eager_load_paths.

  • With Rails 2.3.5, eager_load_paths can be emptied but paths under RAILS_ROOT/app stay on the load paths.
  • With Rails 3.0.11, eager_load_paths can still be emptied (for startup optimization) but it has a side effect: paths under Rails.root/app are no more in the load paths.

This is due to how those paths are now declared in Rails::Engine::Configuration

          paths.app                 "app",                 :eager_load => true, :glob => "*"
          paths.app.controllers     "app/controllers",     :eager_load => true
          paths.app.helpers         "app/helpers",         :eager_load => true
          paths.app.models          "app/models",          :eager_load => true
          paths.app.mailers         "app/mailers",         :eager_load => true

          paths.lib                 "lib",                 :load_path => true

which means only Rails.root/lib is sure to be in the load paths. Other paths get on the load paths because they are eager loaded as "specified" by Rails::Engine.

    def _all_autoload_paths
      @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq
    end

    def _all_load_paths
      @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
    end

A possible fix is

          paths.app                 "app",                 :load_path => true, :eager_load => true, :glob => "*"
          paths.app.controllers     "app/controllers",     :load_path => true, :eager_load => true
          paths.app.helpers         "app/helpers",         :load_path => true, :eager_load => true
          paths.app.models          "app/models",          :load_path => true, :eager_load => true
          paths.app.mailers         "app/mailers",         :load_path => true, :eager_load => true

          paths.lib                 "lib",                 :load_path => true

which prevents app/ paths from being accidentally removed from load_paths.

Not a major annoyance but surely an unattended behaviour.

@arunagw
Ruby on Rails member

Not sure about the issue. But wanted to check if this issue still exists??

@lfarcy

The issue still exists while it is not major. To sum it up, app, app/models, app/controllers, app/helpers and app/mailers are included in the Ruby load path ($LOAD_PATH) by default because the framework eager loads those paths by default.

By configuration, a Rails application can prevent those paths from being eager loaded (by setting config.eager_load_paths to an empty array). But it has the side effect of withdrawing those paths from the Ruby load path. Which is not an expected behaviour.

@ahawkins

@lfarcy so where's the problem?

@rafaelfranca
Ruby on Rails member

I think this is intentional. @josevalim can you confirm? If so we can close this.

@lfarcy

@twinturbo app, app/models, app/controllers, app/helpers and app/mailers shall always be included in $LOAD_PATH however the Rails application is configured.

@rafaelfranca Not sure it's intentional to offload those directories from $LOAD_PATH when playing with config.eager_load_paths...

@goshakkk

Is it still and issue or can it be closed?

@rishav

I think this is intentional. It can be closed .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment