You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 8脚本引入environment后重复执行问题求助

问题原因及解决方案

核心原因

这是因为你的Rails 8生产环境中,bin目录被意外加入到**预加载路径(eager_load_paths)或自动加载路径(autoload_paths)**中,而Rails生产环境会预加载所有这些路径下的Ruby文件。

你的bin/odd脚本是一个Ruby文件,当执行require_relative '../config/environment'时,Rails的Zeitwerk自动加载器会预加载bin目录下的odd.rb,导致整个脚本被第二次执行,从而重复输出quack。

开发环境不会出现这个问题,是因为开发环境默认是按需加载,只有当代码引用到对应常量时才会加载文件,你的脚本里没有触发Odd常量的引用,所以不会重复执行。

验证方法

在bin/odd脚本中添加一行输出当前文件路径的代码,确认是否被执行两次:

#!/usr/bin/env ruby

puts "Executing: #{__FILE__}"
puts 'quack'
require_relative '../config/environment'
puts 'done'

执行生产环境命令后,如果输出两次相同的Executing: .../bin/odd,即可确认是预加载导致的重复执行。

解决方案

  1. 检查并修正加载路径
    打开config/application.rb,查找是否有类似以下代码:

    config.autoload_paths << Rails.root.join('bin')
    config.eager_load_paths << Rails.root.join('bin')
    

    如果有,删除这些行——bin目录不应该被加入到自动加载或预加载路径中。

  2. 修改脚本名称
    如果不想调整加载路径,可以将bin/odd改名为不会被Zeitwerk识别为可加载文件的名称,比如bin/odd_runner(Zeitwerk会将odd.rb映射为Odd常量,改名可避免这种触发)。

  3. 添加执行防护
    在脚本开头添加一个标记,防止重复执行:

    #!/usr/bin/env ruby
    
    # 防止脚本被重复执行
    return if defined?(ODD_SCRIPT_RAN)
    ODD_SCRIPT_RAN = true
    
    puts 'quack'
    require_relative '../config/environment'
    puts 'done'
    

内容的提问来源于stack exchange,提问作者jjg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:17:27