如何在Rails中相关的require,require_dependency和常量重新加载?

wei*_*wei 65 ruby-on-rails require

怎么样requirerequire_dependency不同?
如何require_dependency在开发中自动重新加载类但require不能?

我深入研究了Rails ActiveSupport::Dependencies和dispatcher.rb代码.我在require_dependency代码中看到的是它基本上将常量添加到autoloaded_constants数组中.但是clear_application在每个请求之后它会在内部调度程序中被清除.

有人可以给出明确的解释或指出一些有用的资源吗?

MDa*_*ubs 126

require(和它的堂兄load)是核心的Ruby方法.require_dependency是一种帮助Rails处理依赖关系管理问题的方法.简而言之,它允许Rails在开发模式下重新加载类,这样您每次进行代码更改时都不必重新启动服务器.Rails框架将require_dependency代码,以便在进行更改时可以跟踪和重新加载它.标准的Ruby require不会这样做.作为应用程序(或插件/引擎)开发人员,您不必担心,require_dependency因为这纯粹是Rails内部的.

Rails类加载过程的神奇之处在于ActiveSupport :: Dependencies模块.此代码扩展了默认的Ruby行为,允许Rails应用程序内的代码使用Rails的路径和文件命名约定自动加载模块(包括继承自Module的类).这样就不需要程序员require像在普通的Ruby应用程序中一样调用代码.

换句话说,这使您可以class Admin::User在文件内部进行定义,app/models/admin/user.rb并让Rails知道您Admin::User.new从应用程序的另一部分(如控制器)调用时所说的内容.如果不涉及ActiveSupport :: Dependencies,则必须手动完成require所需的一切.

如果您来自静态类型的语言,如C#,Java等,那么这可能是一个惊喜:Rails代码在需要之前不会加载.例如,User模型类未定义,并且user.rb在您尝试调用之后才会加载User.whatever_method_here.Rails阻止Ruby抱怨缺少常量,加载代码User,然后允许Ruby正常继续.

虽然我无法满足您的特定需求,但如果您确实需要require_dependency在插件或引擎中使用该方法,我会感到非常惊讶.如果你遵循Rails约定,你也不必手动调整$ LOAD_PATH.这不是"Rails方式".

在Ruby和Rails的世界中,简洁和清晰是关键.如果您只想写一个插件或引擎,并且您已经深入内部,那么您可以考虑从不同的角度处理您的问题.我的直觉告诉我,你可能正在尝试做一些不必要的复杂事情.但话说回来,我完全不清楚你在做什么!:)


Kri*_*ris 21

require_dependency当您想要重新打开未在引擎中定义的类(例如在另一个引擎或Rails应用程序中)并重新加载它时,在引擎中很有用.在这种情况下,这样的工作:

# app/controllers/my_engine/documents_controller.rb
require_dependency MyEngine::Engine.root.join('app', 'controllers', 'my_engine', 'documents_controller').to_s

module MyEngine
  class DocumentsController
    def show
      render :text => 'different'
    end
  end
end
Run Code Online (Sandbox Code Playgroud)