Auto-loading lib files in Rails 4

Yarin picture Yarin · Sep 30, 2013 · Viewed 128k times · Source

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?

Answer

ifyouseewendy picture ifyouseewendy · Oct 29, 2013

I think this may solve your problem:

  1. in config/application.rb:

    config.autoload_paths << Rails.root.join('lib')
    

    and keep the right naming convention in lib.

    in lib/foo.rb:

    class Foo
    end
    

    in lib/foo/bar.rb:

    class Foo::Bar
    end
    
  2. if you really wanna do some monkey patches in file like lib/extensions.rb, you may manually require it:

    in config/initializers/require.rb:

    require "#{Rails.root}/lib/extensions" 
    

P.S.