在rails 4中混淆autoload_paths和eager_load_paths

时间:2013-11-04 17:18:33

标签: ruby-on-rails

我读了一篇关于rails load_paths的帖子,这里是link

但是,我仍然对autoload_pathseager_load_paths之间的差异感到困惑:

我在新创建的Rails 4项目中测试了它们。它们似乎以相同的方式运行,即在开发模式下自动重新加载但在生产模式下。

2 个答案:

答案 0 :(得分:137)

此处链接文章的作者。这是为了消除混乱,试图摆脱@ fkreusch的回答。

在Ruby中,您必须要求每个.rb文件才能运行其代码。但是,请注意在Rails中,您从未明确要求app/目录中的任何模型,控制器或其他文件。这是为什么?这是因为在Rails中app/*位于autoload_paths。这意味着当您在开发中运行rails应用程序时(例如通过rails console) - ruby​​实际上并不需要任何模型和控制器。 Rails使用ruby的特殊魔法特性来实际等到代码提到一个常量,比如Book,然后它才会运行require 'book',它会在autoload_paths之一中找到它。这使您可以在开发过程中更快地启动控制台和服务器,因为只有在代码实际需要它时才会启动它。

现在,这种行为对本地开发有利,但生产呢?想象一下,在生产中,您的服务器会执行相同类型的神奇恒定加载(自动加载)。它真的不是世界末日,你在生产中启动你的服务器,人们开始浏览你的页面稍慢,因为有些文件需要自动加载。是的,这几个初始请求的速度较慢,而服务器“预热”,但并不是那么糟糕。除此之外,这不是故事的结局。

如果你在ruby 1.9.x上运行(如果我没记错的话),那么自动要求这样的文件不是线程安全的。因此,如果你使用像puma这样的服务器,你会遇到问题。即使您没有使用多线程服务器,您仍然可能更好地在启动时“主动”需要整个应用程序。这意味着在生产中,您希望在启动应用程序时完全需要每个模型,每个控制器等,并且您不介意更长的启动时间。这称为急切加载。所有ruby文件都被急切地加载,得到它?但是,如果你的rails应用程序没有单require个声明,你怎么能这样做呢?这就是eager_load_paths进来的地方。无论你输入什么内容,生产中启动时都需要这些路径下所有目录中的所有文件。希望这可以解决它。

重要的是要注意eager_load_paths在开发环境中不活跃,因此无论您在开发环境中放置什么,都不会立即急需开发,只能在生产环境中使用。

同样重要的是要注意,只要将某些内容放入autoload_paths中,就不会让它在生产中急于加载。不幸。您还必须明确地将其放入eager_load_paths

另一个有趣的怪癖是,在每个rails应用程序中,app/下的所有目录都自动同时位于autoload_pathseager_load_paths,这意味着在那里添加目录不需要进一步操作。

答案 1 :(得分:10)

基本上,autoload_paths是Rails用来尝试自动加载类的路径。例如。当你致电Book时,如果该类尚未加载,它将通过autoload_paths并在这些路径中查找。

在生产中,最好先预先加载这些内容以避免自动加载并发问题。为此,它提供eager_load_paths。当您的应用程序启动时,将需要预先列出该列表中的路径。