Yar*_*rin 226 ruby-on-rails ruby-on-rails-4
我在初始化程序中使用以下行在/lib
开发期间在我的目录中自动加载代码:
配置/初始化/ custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
Run Code Online (Sandbox Code Playgroud)
(来自Rails 3 Quicktip:在开发模式下自动重新加载lib文件夹)
它运行良好,但在生产中使用效率太低 - 而不是在每个请求上加载库,我只想在启动时加载它们.同一篇博客还有另一篇文章描述了如何做到这一点:
配置/ 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/**/"]
Run Code Online (Sandbox Code Playgroud)
但是,当我切换到它时,即使在开发中,我在尝试使用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
Run Code Online (Sandbox Code Playgroud)
调用Time.milli_stamp
将抛出NoMethodError
我意识到其他人已经在SO上回答了类似的问题,但他们似乎都在处理命名约定和其他我之前不必担心的问题 - 我的lib类已经为每个请求加载工作了,我只是想改变它到per- 启动加载.这样做的正确方法是什么?
ify*_*ndy 547
我认为这可以解决您的问题:
在config/application.rb中:
config.autoload_paths << Rails.root.join('lib')
Run Code Online (Sandbox Code Playgroud)
并在lib中保留正确的命名约定.
在lib/foo.rb中:
class Foo
end
Run Code Online (Sandbox Code Playgroud)
在lib/foo/bar.rb中:
class Foo::Bar
end
Run Code Online (Sandbox Code Playgroud)如果你真的想在lib/extensions.rb这样的文件中做一些猴子补丁,你可以手动要求它:
在config/initializers/require.rb中:
require "#{Rails.root}/lib/extensions"
Run Code Online (Sandbox Code Playgroud)PS
Bill Harding的Rails 3自动加载模块/类.
并了解Rails对自动加载的确切做法是什么?
阅读Rails自动加载 - 它是如何工作的,什么时候不是 Simon Coffey.
lul*_*ala 33
虽然这并没有直接回答这个问题,但我认为这是完全避免这个问题的一个很好的选择.
要避免所有autoload_paths
或eager_load_paths
麻烦,请在"app"目录下创建"lib"或"misc"目录.像往常一样放置代码,Rails将加载文件,就像加载(和重新加载)模型文件一样.
这可能会帮助像我这样的人在搜索Rails如何处理类加载的解决方案时找到这个答案...我发现我必须定义一个module
名称与我的文件名匹配的文件,而不仅仅是定义一个类:
在文件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
Run Code Online (Sandbox Code Playgroud)
工作,但如果我没有把类放在模块中,它就不会加载.