我有一些 Sidekiq worker,它们的命名约定类似于 random_api_worker.rb
,并将类定义为 RandomAPIWorker
,它一直运行到 Rails 6。在在其他情况下,我将类作为 class RandomAPIWorker
开始,尽管它位于几个子目录中,例如 app/workers/dir1/dir2/random_api_worker.rb
我已将 config.autoloader = :classic
添加到我的 application.rb
文件中,但这似乎只有在我在开发中运行所有内容时才有效。在我将 RAILS_ENV
切换到 production
的那一刻,它开始提示工作人员的名字。
这让我想到了两个问题:
- 难道
config.autoloader = :classic
应该忽略这个,还是我误解了它的工作原理? - 是否有可用的 Zeitwerk 脚本可以从根本上升级以适当格式/层次结构的经典 worker 名称?
- 如果 #1 为假,是否有其他方法可以让我的工作人员使用相同的名称,而不必担心重命名他们以满足 Zeitwerk 的要求?
这是我的 application.rb
文件:
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Vspm
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0
config.autoload = :classic
config.autoload_paths << Rails.root.join('app/workers/sampleworkers/**/')
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
config.enable_dependency_loading = true
config.eager_load_paths += Dir["#{config.root}/lib/custom/**/"]
# Add images and subdirectories to asset pipeline
config.assets.paths << "#{Rails.root}/app/assets/images/severity_icons/"
end
这是一个错误(提示其中一个类名中的大写字母):
ubuntu@c567d17a6700:~/myapp/app$ RAILS_ENV=production rails zeitwerk:check
Hold on, I am eager loading the application.
expected file app/services/pdf_generator.rb to define constant PdfGenerator
这是在该文件中定义的类名:
# app/services/pdf_generator.rb
class PDFGenerator
修复此问题后,下一个错误会提示目录层次结构不在工作人员的类名中:
ubuntu@c567d17a6700:~/myapp/app$ RAILS_ENV=production rails zeitwerk:check
Hold on, I am eager loading the application.
expected file app/workers/shared/random_name_worker.rb to define constant Shared::RandomNameWorker
下面是该文件中提到该类的方式:
# app/workers/shared/random_name_worker.rb
class RandomNameWorker
最佳答案
- Isn't the config.autoloader = :classic supposed to ignore this, or am I misunderstanding how this works?
此设置配置 Rails 返回到整个应用程序的 经典模式
加载器,因此它当然会忽略 方便的结构名称。
您可以使用 zeitwerk
设置 autoload_paths
,您的问题是您将嵌套的工作目录添加到 autoload_paths
# NOT THIS
config.autoload_paths << Rails.root.join('app/workers/sampleworkers/**/')
# SHOULD THIS
config.autoload_paths << Rails.root.join('app/workers/sampleworkers/')
# OR THIS (if you want to use `**`)
config.autoload_paths += Dir["#{config.root}/app/workers/**/**"]
# REPLACE
config.autoloader = :classic
# BY
config.load_defaults 6.0
- Is there a Zeitwerk script available that could essentially upgrade classic worker names in a proper format/hierarchy?
我不知道是否有 gem 支持,到目前为止我还没有看到,我手动完成,为每个子目录创建模块,所以你的 worker 变成这样的 Api_Worker::Random
# app/worker/api_worker.rb
module ApiWorker
end
# app/worker/api_worker/random.rb
module ApiWorker
class Random
include Sidekiq::Worker
end
end
- If #1 is false, is there another way to keep my workers with their same names and not have to worry about renaming them to meet the requirements of Zeitwerk?
正如我上面所说,您可以使用 zeitwerk
扩展 autoload_paths
config.autoload_paths += Dir["#{config.root}/app/workers/**/**"]
并且您仍然使用名称 RandomAPIWorker
关于ruby-on-rails - 根据 Zeitwerk 的要求重命名 worker (Rails 5.2.3 到 6 升级),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68735533/