Rails 强制模型快速加载 [英] Rails force models to eager load

查看:30
本文介绍了Rails 强制模型快速加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够加载整个应用程序,以便我可以找到给定类的后代.

I would like to be able to load an entire app so that I may find the descendants of a given class.

例如,我定义了以下类:

For example given I have the following class defined:

# app/models/foo_class.rb
class FooClass < MySpecialBaseClass
  # pasta code
end

它不会被找到:

irb> ObjectSpace.each_object.select { |obj| obj.is_a?(Class) && obj <= MySpecialBaseClass }
=> []

直到我调用常量:

irb> FooClass

然后返回:

irb> ObjectSpace.each_object.select { |obj| obj.is_a?(Class) && obj <= MySpecialBaseClass } 

=> [FooClass]

我该怎么做?

推荐答案

经过大量的反复试验,我最近了解到 Jason Waldrip 的回答有些不完整.从 Rails 5 开始,Rails.application.eager_load! 确实会加载 config/application.rb 中指定的所有目录.但它与 Rails 在生产中的实际行为不符.要做到这一点,你必须镜像 Rails 所做的:

After a great deal of trial and error, I recently learned that Jason Waldrip's answer is somewhat incomplete. As of Rails 5, Rails.application.eager_load! will indeed load all of the directories specified in config/application.rb. But it doesn't match Rails' actual behavior in production. To do that, one must instead mirror what Rails does:

Rails.configuration.eager_load_namespaces.each(&:eager_load!)

这两种方法之间的显着区别在于,OP 不会急切加载位于 gemsvendor 中的 Engine 的应用程序目录中的文件 文件夹.而 Rails 本身识别 Engine 的子类存在的位置,并确保适当的 app 子目录被预先加载.

The salient difference between the approaches is that OPs answer won't eager load the files within app directories of Engines that live in the gems or vendor folders. Whereas Rails itself will identify where subclasses of Engine exist and will see to it that the appropriate app subdirectories are eager-loaded.

幕后

Rails 5 在 railties-5.0.2/lib/rails/engine/configuration.rb:39 中添加了预先加载目录,它运行的地方

Rails 5 adds eager load directories in railties-5.0.2/lib/rails/engine/configuration.rb:39, where it runs

      paths.add "app",                 eager_load: true, glob: "{*,*/concerns}"
      paths.add "app/assets",          glob: "*"
      paths.add "app/controllers",     eager_load: true
      paths.add "app/channels",        eager_load: true, glob: "**/*_channel.rb"
      paths.add "app/helpers",         eager_load: true
      paths.add "app/models",          eager_load: true
      paths.add "app/mailers",         eager_load: true

这些目录当前未包含在默认的Rails.application.eager_load!

These directories are not currently included in a default Rails.application.eager_load!

这篇关于Rails 强制模型快速加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆