Rails 5.1如何让初始化文件区分服务器启动与Rake任务上下文?
如何在Rails 5.1初始化文件里区分服务器启动和Rake任务上下文
嘿,我明白你想在config/my_init.rb里精准判断当前是Web服务器启动(比如rails s)还是在跑Rake任务(比如rake db:seed)的需求,你的初始思路其实方向是对的,但咱们可以把逻辑优化得更清晰、更可靠。
先说说你现有代码的情况
你写的这段代码:
puts "initializing ... #{(!Rails.env.test?) } defined; #{!defined?(::Rake)}" if(!Rails.env.test?) && !defined?(::Rake)
在执行Rake任务时,!defined?(::Rake)确实会返回false——因为这时候Rake环境已经加载了::Rake常量,所以整个条件不成立,不会输出内容,这其实是符合你“非测试且非Rake环境才执行”的预期的。不过咱们可以用更稳妥的方式来做这个判断。
更可靠的判断方法
方法1:用Rails官方提供的方法直接判断Rake任务
Rails 5+自带了**Rails.application.rake_task?**这个方法,专门用来检测当前是否在执行Rake任务,比检查常量定义更靠谱,毕竟官方维护的方法会考虑各种边缘场景:
unless Rails.env.test? if Rails.application.rake_task? puts "当前是Rake任务上下文哦" else puts "现在是Web服务器启动或者控制台这类非Rake环境" end end
方法2:精准区分Web服务器启动场景
如果你想更细分,只在Web服务器启动时执行代码(排除控制台、Spring预加载这些场景),可以结合**defined?(::Rails::Server)**来判断:
unless Rails.env.test? if defined?(::Rails::Server) puts "正在启动Web服务器啦" elsif defined?(::Rake) puts "正在执行Rake任务" else puts "处于其他上下文,比如rails console" end end
方法3:优化你原来的常量判断逻辑
如果你还是想用原来的思路,把代码写得更易读一点会更好:
unless Rails.env.test? if defined?(::Rake) puts "当前在跑Rake任务" else puts "当前是非Rake、非测试环境(比如服务器启动)" end end
这样不管是哪种场景,你都能清晰地判断出来啦~
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

