Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding lib to 'config.autoload_paths' in Rails 3 does not autoload my module

I place a file name g.rb in side Rails.root/lib folder The file content is like this:

module Google
end

Then I add

config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)

to my Rails.root/config/application.rb

However, when I try to invoke Google from rails console, an exception is thrown. The exception goes away only if I execute require 'google'. Why? Shouldn't my file is autoloaded and shouldn't I access the module without any extra require statement?

like image 608
Phương Nguyễn Avatar asked Nov 02 '10 04:11

Phương Nguyễn


3 Answers

Hmm, I discovered an interesting thing. In order for Rails to auto load my class, the class name should be compliant to the file name and the folder structure. For example, if I want to have Google module autoloaded, I must placed it inside google.rb, directly under /lib (incase I specify autoload from /lib). If I want to auto load Google::Docs, then I either place it inside google.rb or google/docs.rb

like image 149
Phương Nguyễn Avatar answered Oct 24 '22 08:10

Phương Nguyễn


I had a similar problem with getting my module to run on Heroku. In addition to the autoload naming convention stated by Stephen C, I found out that the module code must be require'd due to a threadsafe assumption made by the Rails' production environment on Heroku (even though threadsafe was commented out in my production.rb configuration file.) As soon as I require'd the module file before calling include on the module, everything started to work.

require 'mymodule'
include Mymodule

Please take a look at this excellent article on the subject of getting Modules to load correctly in Heroku (production).

like image 35
Don Leatham Avatar answered Oct 24 '22 08:10

Don Leatham


That's because the point of autoload is not to 'require' everything up front (startup penalty). Classes are loaded as they are needed/referenced. In order to do this, you need some way to know where to look for the class. Otherwise, you would have to load every file in the autoload directory in advance to see what classes are declared. It's a tradeoff, but requiring everything in advance (as marbaq suggests) is not autoloading. You can use the autoload command as provided by Ruby, which takes two arguments, the module to load (symbolized, i.e. :Google in your case), and the second argument is the filename, which would be g.rb if lib is in your load path ($:). See the Ruby docs for autoload.

like image 24
Stephen C Avatar answered Oct 24 '22 06:10

Stephen C