Permalink
Browse files

The algorithm of auto-loading paths in Rails 3 is a bit wried when cl…

…ass caching is turned off:

Assuming you added all subdirectories under app/models into the load paths:

config.autoload_paths += Dir["#{config.root}/app/models/**/"]

And you have a subdirectory under app/models with name class1 and a file under this subdirectory with name class1.rb. When you are referring any classes under this subdirectory in class1.rb, you have to make sure they are in the namespace of Class1. Otherwise it will complain about your referred class is not in the namespace of Class1. The directory structure looks like this:

/app
	/models
		/class1
			/class1.rb
			/class1_reference.rb

When you refer to Class1Reference in Class1, you will get "Expected app/models/class1/class1_reference.rb to define Class1::Class1Reference". If the subdirectory is not named class1, the example will work. A comparing example directory structure is like this:

/app
	/models
		/not_class2
			/class2.rb
			/class2_reference.rb

The second example have everything the same as the first one except that the subdirectory name is different from the file name (in this case "class2"). 

This result indicates either an expected behaviour in naming convention in Rails 3 or a protential bug in the path loading algorithm. Details implementation in https://github.com/rails/rails/blob/master/activesupport/lib/active_support/dependencies.rb. 

Please note that if class caching is turned on, both cases work.
  • Loading branch information...
jingweno committed Jan 20, 2011
1 parent 1d53fb3 commit 13449f23d76ab59614f8c8218c7a2aa682a7ef01
@@ -1,3 +1,8 @@
class ApplicationController < ActionController::Base
protect_from_forgery
+
+ rescue_from 'Exception' do |exception|
+ @exception = exception
+ render :error
+ end
end
@@ -0,0 +1,11 @@
+class SubdirectoryNamingConventionController < ApplicationController
+ def class1
+ @msg = Class1.new.call_reference
+ render :success
+ end
+
+ def class2
+ @msg = Class2.new.call_reference
+ render :success
+ end
+end
@@ -0,0 +1,5 @@
+class Class1
+ def call_reference
+ Class1Reference.new.call
+ end
+end
@@ -0,0 +1,5 @@
+class Class1Reference
+ def call
+ "#{self.class.name} is called"
+ end
+end
@@ -0,0 +1,5 @@
+class Class2
+ def call_reference
+ Class2Reference.new.call
+ end
+end
@@ -0,0 +1,5 @@
+class Class2Reference
+ def call
+ "#{self.class.name} is called"
+ end
+end
@@ -0,0 +1,5 @@
+<% unless @exception.nil? %>
+<div id="error_explanation">
+ <h3><%= @exception.message %></h3>
+</div>
+<% end %>
@@ -0,0 +1,3 @@
+<div class="field">
+ <h2><%= @msg %></h2>
+</div>
View
@@ -1,4 +1,7 @@
AutoloadInRails3::Application.routes.draw do
+ match 'class1' => 'subdirectory_naming_convention#class1'
+ match 'class2' => 'subdirectory_naming_convention#class2'
+
# The priority is based upon order of creation:
# first created -> highest priority.
@@ -31,7 +31,7 @@ div.field, div.actions {
}
#error_explanation {
- width: 450px;
+ width: 1050px;
border: 2px solid red;
padding: 7px;
padding-bottom: 0;

0 comments on commit 13449f2

Please sign in to comment.