Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a good way to require a whole directory tree in Rails?

I am using Rails 3.2.2 and want to load all the code in a certain directory recursively. For example:

[Rails root]/lib/my_lib/my_lib.rb
[Rails root]/lib/my_lib/subdir/support_file_00.rb
[Rails root]/lib/my_lib/subdir/support_file_01.rb
...    

Based on Googling, I tried:

config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/**"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/**/"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/**/*"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/{**}"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/{**}/"]

None of these load any of the code and I get "uninitialized constant" errors.

This loads files directly in /my_lib/, but not subdirectories:

config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib"]

UPDATE

Thanks for the comments.

I put this in my application.rb:

Dir["#{Rails.root.to_s}/lib/**/*.rb"].each { |file| config.autoload_paths += [file] }

The application launches but classes declared in my library are not available:

> MyClass
NameError: uninitialized constant MyClass
like image 291
Ethan Avatar asked Apr 16 '12 00:04

Ethan


1 Answers

autoload_paths and friends work only if the given files, or files in the given directories, are named according to the rails naming conventiion.

e.g. if a file some_class.rb is given to autoload_paths, it expcects the file to declare a class SomeClass, and sets up some magic to make any reference to SomeClass load that file on-the-fly.

So if you want to have it only load each of your files as they are needed, then you will have to name your files accordingly, and have one file per class.

If you are happy to load all of the files in a directory tree when rails starts, you can do this:

Dir.glob("/path/to/my/lib/**/*.rb").each { |f| require f }

The above will read every .rb file in /path/to/my/lib, and any directories under it.

like image 54
Michael Slade Avatar answered Oct 03 '22 23:10

Michael Slade