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

升级Rails至7.1.3后运行zeitwerk:check报SvgGenerator未初始化常量错误

Rails 7.1.3升级后rails zeitwerk:check报NameError: uninitialized constant SvgGenerator错误排查

问题描述

升级Rails应用至7.1.3版本后,执行rails zeitwerk:check命令时触发NameError: uninitialized constant SvgGenerator错误,Zeitwerk自动加载器无法找到指定常量。

错误堆栈信息

NameError: uninitialized constant SvgGenerator (NameError)

parent.const_get(cname, false)
       ^^^^^^^^^^
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/helpers.rb:135:in `const_get'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/helpers.rb:135:in `cget'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:175:in `block in actual_eager_load_dir'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/helpers.rb:40:in `block in ls'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/helpers.rb:25:in `each'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/helpers.rb:25:in `ls'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:170:in `actual_eager_load_dir'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:17:in `block (2 levels) in eager_load'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:16:in `each'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:16:in `block in eager_load'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:10:in `synchronize'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/eager_load.rb:10:in `eager_load'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:379:in `block in eager_load_all'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:377:in `each'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:377:in `eager_load_all'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/zeitwerk_checker.rb:6:in `check'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/tasks/zeitwerk.rake:29:in `block (2 levels) in <top (required)>'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:281:in `block in execute'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:281:in `each'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:281:in `execute'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:199:in `synchronize'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:199:in `invoke_with_call_chain'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/task.rb:188:in `invoke'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:182:in `invoke_task'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:138:in `block (2 levels) in top_level'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:138:in `each'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:138:in `block in top_level'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:147:in `run_with_threads'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:132:in `top_level'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/commands/rake/rake_command.rb:27:in `block (2 levels) in perform'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/application.rb:208:in `standard_exception_handling'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/commands/rake/rake_command.rb:27:in `block in perform'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/commands/rake/rake_command.rb:44:in `block in with_rake'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rake-13.1.0/lib/rake/rake_module.rb:59:in `with_application'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/commands/rake/rake_command.rb:41:in `with_rake'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/command.rb:156:in `invoke_rake'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/command.rb:73:in `block in invoke'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/command.rb:149:in `with_argv'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/command.rb:69:in `invoke'
/Users/dmorin/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.3/lib/rails/commands.rb:18:in `<top (required)>'
bin/rails:9:in `require'
bin/rails:9:in `<main>'
Tasks: TOP => zeitwerk:check

相关代码片段

lib/rails_admin/config/actions/svg_generator.rb

require 'rails_admin/config/actions'
require 'rails_admin/config/actions/base'

module RailsAdmin
  module Config
    module Actions
      class SvgGenerator < RailsAdmin::Config::Actions::Base
        RailsAdmin::Config::Actions.register(self)

        register_instance_option :member? do
          true
        end
        ...
      end
    end
  end
end

config/initializers/rails_admin.rb

require "#{Rails.root}/lib/rails_admin/config/actions/svg_generator"

RailsAdmin.config do |config|
  config.asset_source = :sprockets

  ### Popular gems integration

  # == Devise ==
  config.authenticate_with do
    warden.authenticate! scope: :user
  end
  config.current_user_method(&:current_user)

  # == Cancan ==
  config.authorize_with :cancancan

  ## == Pundit ==
  # config.authorize_with :pundit

  ## == PaperTrail ==
  config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0

  ### More at https://github.com/sferik/rails_admin/wiki/Base-configuration

  ## == Gravatar integration ==
  ## To disable Gravatar integration in Navigation Bar set to false
  # config.show_gravatar true

  config.main_app_name = ['CHU de Québec - Plans Interactifs', 'Admin']

  PAPER_TRAIL_AUDIT_MODEL = %w(Point Portal Path)
  config.actions do
    dashboard                     # mandatory
    index                         # mandatory
    new
    export
    bulk_delete
    show
    edit
    delete
    show_in_app
    nestable

    svg_generator do
      visible do
        'Hospital' == bindings[:abstract_model].model_name
      end
    end

    ## With an audit adapter, you can add:
    history_index do
      only PAPER_TRAIL_AUDIT_MODEL
    end
    history_show do
      only PAPER_TRAIL_AUDIT_MODEL
    end

    config.model Floor do
      nestable_list({
        position_field: :index
      })
    end
  end
end

问题原因

  1. Zeitwerk加载规则冲突:Zeitwerk自动加载器会根据文件路径推断常量名,lib/rails_admin/config/actions/svg_generator.rb对应的正确常量应为RailsAdmin::Config::Actions::SvgGenerator,但Zeitwerk在预加载时错误尝试查找顶级常量SvgGenerator,而该类实际嵌套在RailsAdmin::Config::Actions模块下。
  2. 语法错误影响加载:原代码中register_instance_option :member? do块未正确闭合,导致类定义不完整,无法被正常加载。
  3. 手动require与自动加载冲突:在初始化文件中手动require了该文件,但Zeitwerk仍会尝试自动加载该路径下的文件,引发加载逻辑冲突。

解决方案

1. 修复代码语法错误

确保svg_generator.rb中的所有代码块正确闭合,补全register_instance_option :member?对应的end,并确保整个类的模块层级正确闭合(添加缺失的end)。

2. 让Zeitwerk忽略Rails Admin自定义动作目录

在config/application.rb中添加配置,阻止Zeitwerk自动加载lib/rails_admin目录,避免与手动加载逻辑冲突:

# 确保lib目录被加入加载路径
config.autoload_paths << Rails.root.join('lib')
config.eager_load_paths << Rails.root.join('lib')

# 让Zeitwerk忽略rails_admin目录
config.zeitwerk_loader.ignore(Rails.root.join('lib/rails_admin'))

3. 验证修复效果

执行以下命令验证问题是否解决:

rails zeitwerk:check

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:05:53