在开发过程中,我在初始化器中使用以下行来自动加载/lib目录中的代码:

配置/初始化/ custom.rb:

RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?

(来自Rails 3快速提示:在开发模式下自动重载库文件夹)

它工作得很好,但在生产中使用效率太低——我不想在每个请求上加载程序库,而只想在启动时加载它们。同一博客还有另一篇文章描述了如何做到这一点:

配置/ 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/**/"]

然而,当我切换到它时,即使在开发中,当我尝试使用lib函数时,我得到NoMethodErrors。

我的lib文件的一个例子:

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

调用Time.milli_stamp将抛出NoMethodError

我意识到其他人已经回答了关于SO的类似问题,但他们似乎都处理了命名约定和其他问题,我以前不必担心-我的lib类已经为每个请求加载工作,我只是想把它改为每次启动加载。正确的做法是什么?


我认为这可以解决你的问题:

在config / application.rb: 配置。autoload_paths << Rails.root.join('lib') 并在lib中保持正确的命名约定。 在lib / foo.rb: 类Foo 结束 在lib / foo / bar.rb: 类Foo:酒吧 结束 如果你真的想在文件中做一些猴子补丁,比如lib/extensions。Rb,你可以手动要求它: 在config /初始化/ require.rb: 需要“# {Rails.root} / lib /扩展”

注:

Rails 3自动加载模块/类Bill Harding。 了解Rails在自动加载方面到底做了什么? 阅读Simon Coffey的Rails自动加载——它是如何工作的,什么时候不起作用。


这可能会帮助像我这样的人在寻找Rails如何处理类加载的解决方案时找到这个答案……我发现我必须定义一个名称与我的文件名匹配的模块,而不仅仅是定义一个类:

在lib/development_mail_interceptor文件中。rb(是的,我使用来自Railscast的代码:))

module DevelopmentMailInterceptor
  class DevelopmentMailInterceptor
    def self.delivering_email(message)
      message.subject = "intercepted for: #{message.to} #{message.subject}"
      message.to = "myemail@mydomain.org"
    end
  end
end

工作,但它不加载,如果我没有把类放在一个模块。


虽然这并没有直接回答问题,但我认为这是一个很好的选择,可以完全避免这个问题。

为了避免所有autoload_paths或eager_load_paths的麻烦,在“app”目录下创建一个“lib”或“misc”目录。像通常那样放置代码,Rails将像加载(和重新加载)模型文件一样加载文件。


使用配置。准备在开发模式下为每个请求加载monkey补丁/扩展。

config.to_prepare do |action_dispatcher|
 # More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
 Rails.logger.info "\n--- Loading extensions for #{self.class} "
 Dir.glob("#{Rails.root}/lib/extensions/**/*.rb").sort.each do |entry|
   Rails.logger.info "Loading extension(s): #{entry}"
   require_dependency "#{entry}"
 end
 Rails.logger.info "--- Loaded extensions for #{self.class}\n"

end