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

如何通过Zeitwerk为packages下public目录添加自定义命名空间?

解决方案

1. 调整应用加载路径,避免public目录被顶级加载

修改config/application.rb中的packages路径配置,将public目录排除在顶级加载路径之外,只保留priv和concerns:

# config/application.rb
module MyApp
  class Application < Rails::Application
    config.load_defaults 6.0

    # 仅加载每个pack下的priv和concerns目录作为顶级路径
    config.paths.add 'packages', glob: '*/{priv,concerns}', eager_load: true
    ...
  end
end

2. 配置Zeitwerk命名空间映射

在config/initializers/zeitwerk.rb中,为每个pack的public目录指定对应的模块命名空间,让Zeitwerk知道该目录下的类属于PackName模块:

# config/initializers/zeitwerk.rb
Rails.autoloaders.each do |autoloader|
  autoloader.inflector.inflect(
    "my_wrapper" => "MyWrapper", # ActiveAdmin class
  )

  autoloader.ignore(Rails.root.join('packages/ops/admin'))

  # 动态为所有pack的public目录绑定命名空间
  Dir.glob(Rails.root.join('packages/*/public')).each do |public_dir|
    # 从路径提取pack名称(如pack_name)
    pack_name = File.basename(File.dirname(public_dir))
    # 转换为驼峰模块名(如PackName)
    module_const = ActiveSupport::Inflector.camelize(pack_name).constantize
    # 将public目录映射到对应的模块
    autoloader.push_dir(public_dir, namespace: module_const)
  end
end

3. 调整public目录下的文件结构

确保service_one.rb等文件的代码包裹在对应模块中,示例如下:

# packages/pack_name/public/service_one.rb
module PackName
  class ServiceOne
  end
end

验证效果

重启应用后,你就可以通过PackName::ServiceOne、PackName::ServiceTwo的形式访问这些服务,而priv目录下的文件仍保持原有的顶级常量访问方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:19:01