This project is archived and is in readonly mode.
Autoloading behaves weird when class caching is turned off
-
Owen
More detail is available at my blog post with comparing examples: http://owenou.com/2011/01/20/loading-path-gotchas-in-rails3.html
-
tsailipu
I am investigating this potential bug with a different twist. Glad to find this post and bug report.
My example is having:
app/models/user.rb
app/models/Modu/user.rband have autoload_path::
config.autoload_paths += %W(#{config.root}/app/models/Modu)Where app/models/user.rb is simply:
class User puts "hi User" endand app/Modu/user.rb is simply:
module Modu class User puts "hi Modu::User" end endUpon "rails c" or "rails server," the following exception will occur:
hi Modu::User /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:492:in `load_missing_constant': Expected /Users/apps/xyz/app/models/Modu/user.rb to define User (LoadError) -
tsailipu
BTW, the bug I reported above happens regardless of caching.
-
José Valim
- State changed from new to wontfix
- Importance changed from to Low
Rails is panicking when you add subdirectories of a given directory to autoload paths. In both cases, you will have in the load paths both app/models/ and app/models/client1 (or app/models/Modu) and then Rails heuristic to find which model to load is picking up the one you do not expect to. The ideal way is to not include subdirectories in autoload paths and reference the constants using namespaces.
-
Owen
Hi José,
How about my example? I don't have two classes with the same name. I have a subdirectory named class1 and a file under it named class1.rb. If class1.rb refers to class1reference.rb, if will also raise exception. I have documented it with a blog post: http://owenou.com/2011/01/20/loading-path-gotchas-in-rails3.html. Please take a look. Thanks.
-
José Valim
Owen, but you still have app/models/client1 which is a directory. Rails get confused about defining a module with client1 (which it does automatically for directories) or loading the module (which would define a class). Again, the origin of the issue is the same, having a subpath inside another in autoload_paths. This causes ambiguity and any way Rails try to solve it will likely clause conflicts.
-
Owen
Thanks for the clarification, José. So what's the best practice to manage subdirectories in Rails 3? I have too many models and I would like to manage them in different directories. Should I still organize them by having a base file "require" all the files in the subdirectories?
-
tsailipu
Sounds like Rails 3 could improve the loading logic: remember the path to the class, then when asked and if there are classes with the same name, check to see whether the references have the path, if not, complain. Bailing out during "rails c" or "rails server" when an autoload path contains the same class name as another in the default app/models path renders Rails 3 brittle.... BTW, Jose, I don't know what changed, but the example I quoted doesn't have a problem in Rails 2 (e.g. 2.3.5). So I don't know why you wouldn't think this is something worth looking into in Rails 3. Thanks for the explanation!
-
Owen
Hi José, can you provide recommendations on how to manage subdirectories in Rails 3. Thanks!
-
myopenid.com (at bobics)
- Tag changed from class cache, class reloading, autoload to class cache, class reloading, autoload, sti
I realize this ticket is marked "wontfix" but I'd like to add a use case where loading subfolder without a namespace makes sense. My current issue is that I want to use Single Table Inheritance and organize the sub classes in a folder. I should be able to use:
class Automobile ... end
class Car < Automobile ... end
class Truck < Automobile ... endAnd put car.rb and truck.rb under a folder "automobile" without having to scope them. If I use the following:
class Automobile::Car < Automobile ... end
Then I get "Automobile::Car" in the "type" column for STI. This is definitely NOT what I want, I'd rather just have "Car".