我注意到当我修改Rails项目文件,例如html.erb
或.css
时,我不用使用rails -s
命令重新启动服务器。
但是,我认为当我想要安装新的gem时,我必须重新启动。问题是我正试图让jQuery工作,所以我厌倦了一遍又一遍地执行rails -s
。
有谁能告诉我何时必须再次运行rails -s
来修改我的应用程序,何时可以免费不这样做?所谓不这样做,就是简单地刷新网页以查看更改。
我注意到当我修改Rails项目文件,例如html.erb
或.css
时,我不用使用rails -s
命令重新启动服务器。
但是,我认为当我想要安装新的gem时,我必须重新启动。问题是我正试图让jQuery工作,所以我厌倦了一遍又一遍地执行rails -s
。
有谁能告诉我何时必须再次运行rails -s
来修改我的应用程序,何时可以免费不这样做?所谓不这样做,就是简单地刷新网页以查看更改。
由于这个答案是我在StackOverflow上最受关注的答案,而且它已经相当老了,所以我认为是时候更新一下,让它更加深入一些。它的原始信息并没有错误,但有点太笼统了,我觉得我现在可以用我的知识更好地解释它。原始答案保留如下。
Rails与纯Ruby的工作方式基本上是在您不需要在文件顶部添加require
的情况下即时要求您的文件。现在官方Rails指南上有一个相对详细的页面,介绍了它的工作原理,页面在这里。
从Rails 6开始,他们引入了一个新的加载器来管理自动加载源文件的逻辑,将这项工作转移到了一个名为zeitwerk的gem中。Rails指南上也有一篇页面,解释了新加载器的工作原理。
基本思路是这样的:
Rails运行一系列配置文件(environment.rb
、application.rb
、boot.rb
、相应的environments/<environment>.rb
、config/routes.rb
、initializers等)。所有在此启动阶段运行的文件都在config
目录中,所以如果更改的文件在config
目录中,它可能需要重新启动Rails。
Rails然后开始监视其每个autoload_paths
下的所有文件(默认情况下在app
目录中的每个文件夹),以检查它们何时更改。它还专门监视config/routes.rb
文件的更改。
现在拥有了一个很好的路由配置,Rails知道要响应哪些路径并使用哪些控制器。一旦您访问了其中一个配置的路由,Rails将运行您的控制器操作。
每当Ruby看到一个未识别的常量时,它就会调用方法const_missing
。Rails覆盖此方法以获取您的常量名称并使用它来搜索autoload_paths
中每个目录中具有相同名称的文件。
当它找到文件时,它会即时地要求该文件,假定它将定义触发const_missing
的常量,然后代码继续执行。
下次使用相同的常量时,它现在已被定义,因此它甚至不会到达const_missing
方法。
最后但并非最不重要的是,如果配置cache_classes
设置为false
(在开发环境中默认值),则每当Rails捕获到它正在监视的文件中的更改时,它都会取消与该文件关联的常量(它从文件名知道)。
因此,每当您需要更改步骤1中加载的任何内容(除了特别处理的config/routes.rb
),您都需要重新启动Rails。其他任何内容,Rails都将通过自动加载机制重新加载,除非它设置为缓存结果。
在生产环境中,默认情况下也配置为预加载类,因此它将在启动服务器之前加载所有类。这是为了避免整个const_missing
、文件搜索和动态require
过程的开销。
非Ruby文件(如资源和视图)都是在请求时由Rails读取的,因此您可以随时更改它们而无需重新启动Rails。(注意:在生产中,资源通常是预编译的,因此更改app/assets
中的资源不会导致任何更改。但它仍然在请求时加载,只是相关文件是在public
目录中的已编译捆绑包)。
当你需要重新加载Rails时,需要重新启动服务器。
如果你添加或删除了gems,那么是的,你需要重新启动服务器。
如果你更改了ruby版本、更改了Gemfile或更改了Rails内部类的某些内容,你需要重新启动服务器,否则应该没问题。但如果出现意外问题,重新启动服务器是你应该尝试的第一件事。
另外,顺带提一下,只有在config.cache_classes
设置为false
时(我认为这是开发环境的默认设置,但不是生产环境),刷新页面才会看到更改。
编辑:
为了确保每个人都能注意到,tadman在评论中说了一句明智的话:通常情况下,在app/或config/routes.rb或db/之外进行更改都需要重新启动服务器。
app/
或config/routes.rb
之外的任何内容进行更改都需要重新启动。 - tadmangit pull
命令,一切都应该会被更新吗?(除了资源文件,我猜) - antoineMoPaconfig.cache_classes
设置为 true
,那么仅刷新页面是否无法显示更改?应该采取什么措施?即使您对 app/
或 routes.rb
中的文件进行了更改,也应重新启动整个服务器吗? - Fedconfig.cache_classes
设置为 true
,则任何 Ruby 代码都需要重新启动服务器。但是,如果更改视图或 js 文件,则仍然可以正常工作。请注意,此答案相当古老,事情从那时到现在已经有了一些变化,但基本原理仍然基本相同。 - Doodad在开发中,你需要重新启动应用程序当:
Gemfile
中添加/删除/更新gem包。rvm
修改了ruby环境。config/
下的任何文件,但routes.rb
会自动重新加载。require
载入的文件时做出更改,而不是使用自动加载。在生产中,你需要重新启动应用程序当:
注: 如果需要,可以通过编辑相应的environment/<env>.rb
文件来更改这些行为,尽管默认值很明智。