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

使用Apartment gem时ActiveStorage仅查询public schema加载文件问题

解决ActiveStorage在Apartment多租户架构下的404问题

你遇到的问题核心是ActiveStorage的内置控制器没有触发Apartment的租户切换逻辑——虽然你配置了Apartment::Elevators::Subdomain中间件,但Rails内置的ActiveStorage路由对应的控制器(比如ActiveStorage::Representations::ProxyController)未被中间件正确处理,导致查询Blob时始终停留在public schema,最终抛出找不到记录的错误。

试试下面几个针对性的解决方案:

方案1:调整Apartment中间件优先级

确保Apartment的租户切换中间件在ActiveStorage相关路由处理之前执行,让所有请求(包括图片访问请求)先完成租户切换:

# config/application.rb
# 将Apartment电梯中间件插入到路由处理中间件之前
config.middleware.insert_before ActionDispatch::Routing::RouteSet, Apartment::Elevators::Subdomain

方案2:给ActiveStorage控制器手动添加租户切换钩子

创建一个Concern,让ActiveStorage的所有核心控制器继承租户切换逻辑:

# app/controllers/concerns/active_storage_tenant_switch.rb
module ActiveStorageTenantSwitch
  extend ActiveSupport::Concern

  included do
    around_action :switch_tenant_by_subdomain
  end

  private

  def switch_tenant_by_subdomain
    # 根据请求子域名匹配对应租户
    tenant = Tenant.find_by(subdomain: request.subdomain)
    if tenant
      Apartment::Tenant.switch(tenant.schema_name) { yield }
    else
      yield # 无匹配租户时 fallback 到public schema
    end
  end
end

然后在初始化文件中让ActiveStorage的控制器加载这个Concern:

# config/initializers/active_storage_tenant.rb
ActiveStorage::Representations::ProxyController.include(ActiveStorageTenantSwitch)
ActiveStorage::Blobs::RedirectController.include(ActiveStorageTenantSwitch)
ActiveStorage::DiskController.include(ActiveStorageTenantSwitch)

方案3:验证租户schema的ActiveStorage表完整性

虽然你提到上传时Blob会存入正确租户schema,但仍需确认每个租户schema中都存在active_storage_blobs和active_storage_attachments表。可以通过Apartment的创建钩子,确保新租户生成时自动执行ActiveStorage迁移:

# config/initializers/apartment.rb
Apartment.configure do |config|
  # 其他现有配置...
  config.on_create = ->(schema) {
    ActiveRecord::Base.connection.schema_search_path = schema
    # 执行所有未完成的迁移(包括ActiveStorage的)
    ActiveRecord::MigrationContext.new(Rails.root.join('db', 'migrate')).migrate
    ActiveRecord::Base.connection.schema_search_path = 'public'
  }
end

额外检查项:确认图片访问请求的子域名与上传时的租户子域名完全一致——部分CDN或反向代理可能修改请求头,导致Apartment无法正确识别租户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:26:06