I use the following line in an initializer to autoload code in my /lib
directory during development:
config/initializers/custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(from Rails 3 Quicktip: Auto reload lib folders in development mode)
It works great, but it's too inefficient to use in production- Instead of loading libs on each request, I just want to load them on start up. The same blog has another article describing how to do this:
config/application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
However, when I switch to that, even in development, I get NoMethodErrors when trying to use the lib functions.
Example of one of my lib files:
lib/extensions.rb:
Time.class_eval do
def self.milli_stamp
Time.now.strftime('%Y%m%d%H%M%S%L').to_i
end
end
Calling Time.milli_stamp
will throw NoMethodError
I realize others have answered similar questions on SO but they all seem to deal with naming conventions and other issues that I didn't to have to worry about before- My lib classes already worked for per-request loading, I just want to change it to per-startup loading. What's the right way to do this?
This might help someone like me that finds this answer when searching for solutions to how Rails handles the class loading ... I found that I had to define a
module
whose name matched my filename appropriately, rather than just defining a class:In file lib/development_mail_interceptor.rb (Yes, I'm using code from a Railscast :))
works, but it doesn't load if I hadn't put the class inside a module.
Though this does not directly answer the question, but I think it is a good alternative to avoid the question altogether.
To avoid all the
autoload_paths
oreager_load_paths
hassle, create a "lib" or a "misc" directory under "app" directory. Place codes as you would normally do in there, and Rails will load files just like how it will load (and reload) model files.Use config.to_prepare to load you monkey patches/extensions for every request in development mode.
end
I think this may solve your problem:
in config/application.rb:
and keep the right naming convention in lib.
in lib/foo.rb:
in lib/foo/bar.rb:
if you really wanna do some monkey patches in file like lib/extensions.rb, you may manually require it:
in config/initializers/require.rb:
P.S.
Rails 3 Autoload Modules/Classes by Bill Harding.
And to understand what does Rails exactly do about auto-loading?
read Rails autoloading — how it works, and when it doesn't by Simon Coffey.