在Rails中,什么情况下需要重启服务器?

54

我注意到当我修改Rails项目文件,例如html.erb.css时,我不用使用rails -s命令重新启动服务器。

但是,我认为当我想要安装新的gem时,我必须重新启动。问题是我正试图让jQuery工作,所以我厌倦了一遍又一遍地执行rails -s

有谁能告诉我何时必须再次运行rails -s来修改我的应用程序,何时可以免费不这样做?所谓不这样做,就是简单地刷新网页以查看更改。


3个回答

68

2021更新:

由于这个答案是我在StackOverflow上最受关注的答案,而且它已经相当老了,所以我认为是时候更新一下,让它更加深入一些。它的原始信息并没有错误,但有点太笼统了,我觉得我现在可以用我的知识更好地解释它。原始答案保留如下。

Rails与纯Ruby的工作方式基本上是在您不需要在文件顶部添加require的情况下即时要求您的文件。现在官方Rails指南上有一个相对详细的页面,介绍了它的工作原理,页面在这里

从Rails 6开始,他们引入了一个新的加载器来管理自动加载源文件的逻辑,将这项工作转移到了一个名为zeitwerk的gem中。Rails指南上也有一篇页面,解释了新加载器的工作原理。

基本思路是这样的:

  1. Rails运行一系列配置文件(environment.rbapplication.rbboot.rb、相应的environments/<environment>.rbconfig/routes.rb、initializers等)。所有在此启动阶段运行的文件都在config目录中,所以如果更改的文件在config目录中,它可能需要重新启动Rails。

  2. Rails然后开始监视其每个autoload_paths下的所有文件(默认情况下在app目录中的每个文件夹),以检查它们何时更改。它还专门监视config/routes.rb文件的更改。

  3. 现在拥有了一个很好的路由配置,Rails知道要响应哪些路径并使用哪些控制器。一旦您访问了其中一个配置的路由,Rails将运行您的控制器操作。

  4. 每当Ruby看到一个未识别的常量时,它就会调用方法const_missing。Rails覆盖此方法以获取您的常量名称并使用它来搜索autoload_paths中每个目录中具有相同名称的文件。

  5. 当它找到文件时,它会即时地要求该文件,假定它将定义触发const_missing的常量,然后代码继续执行。

  6. 下次使用相同的常量时,它现在已被定义,因此它甚至不会到达const_missing方法。

  7. 最后但并非最不重要的是,如果配置cache_classes设置为false(在开发环境中默认值),则每当Rails捕获到它正在监视的文件中的更改时,它都会取消与该文件关联的常量(它从文件名知道)。

因此,每当您需要更改步骤1中加载的任何内容(除了特别处理的config/routes.rb),您都需要重新启动Rails。其他任何内容,Rails都将通过自动加载机制重新加载,除非它设置为缓存结果。

在生产环境中,默认情况下也配置为预加载类,因此它将在启动服务器之前加载所有类。这是为了避免整个const_missing、文件搜索和动态require过程的开销。

非Ruby文件(如资源和视图)都是在请求时由Rails读取的,因此您可以随时更改它们而无需重新启动Rails。(注意:在生产中,资源通常是预编译的,因此更改app/assets中的资源不会导致任何更改。但它仍然在请求时加载,只是相关文件是在public目录中的已编译捆绑包)。


Translated answer:

当你需要重新加载Rails时,需要重新启动服务器。

如果你添加或删除了gems,那么是的,你需要重新启动服务器。

如果你更改了ruby版本、更改了Gemfile或更改了Rails内部类的某些内容,你需要重新启动服务器,否则应该没问题。但如果出现意外问题,重新启动服务器是你应该尝试的第一件事。

另外,顺带提一下,只有在config.cache_classes设置为false时(我认为这是开发环境的默认设置,但不是生产环境),刷新页面才会看到更改。

编辑:

为了确保每个人都能注意到,tadman在评论中说了一句明智的话:通常情况下,在app/或config/routes.rb或db/之外进行更改都需要重新启动服务器。


12
在这里的一般经验法则是,对app/config/routes.rb之外的任何内容进行更改都需要重新启动。 - tadman
那么在这种情况下,我们只需要执行 git pull 命令,一切都应该会被更新吗?(除了资源文件,我猜) - antoineMoPa
如果将 config.cache_classes 设置为 true,那么仅刷新页面是否无法显示更改?应该采取什么措施?即使您对 app/routes.rb 中的文件进行了更改,也应重新启动整个服务器吗? - Fed
如果将 config.cache_classes 设置为 true,则任何 Ruby 代码都需要重新启动服务器。但是,如果更改视图或 js 文件,则仍然可以正常工作。请注意,此答案相当古老,事情从那时到现在已经有了一些变化,但基本原理仍然基本相同。 - Doodad

20

在开发中,你需要重新启动应用程序当:

  • 你在Gemfile中添加/删除/更新gem包。
  • 你通过rvm修改了ruby环境。
  • 你更改了config/下的任何文件,但routes.rb会自动重新加载。
  • 你手动要求require载入的文件时做出更改,而不是使用自动加载。

在生产中,你需要重新启动应用程序当:

  • 你更改了任何代码或gem包。

注: 如果需要,可以通过编辑相应的environment/<env>.rb文件来更改这些行为,尽管默认值很明智。


2
一般情况下,当安装或更新gem、升级ruby或更改在启动时运行的某些逻辑(如config/boot.rb或config/database.yml)时,您通常需要重新启动服务器。否则,即使您编辑/添加模型/控制器,通常也可以不进行重启。
顺便提一下,jquery-rails gem可以轻松地将jquery添加到项目中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接