Rails Active Storage多服务配置场景下direct upload功能异常问题求助
你没有遗漏配置,这是Rails Active Storage默认直传实现的原生限制:默认的DirectUploadsController创建Blob时固定使用全局配置的默认存储服务,不会自动读取关联模型指定的service参数。
可行解决方案:自定义直传控制器,支持指定服务
步骤1:创建自定义直传控制器
继承官方的ActiveStorage::DirectUploadsController,重写Blob创建逻辑,增加service_name参数的白名单校验和支持:
# app/controllers/custom_direct_uploads_controller.rb class CustomDirectUploadsController < ActiveStorage::DirectUploadsController def create blob = ActiveStorage::Blob.create_before_direct_upload!( **blob_args.merge(service_name: allowed_service_name) ) render json: direct_upload_json(blob) end private # 服务名校验白名单,避免恶意参数调用未授权存储服务 def allowed_service_name permitted_services = %w[amazon unsafe_files] params[:service_name].presence_in(permitted_services) || ActiveStorage::Blob.service.name end # 扩展参数白名单,允许接收service_name def blob_args super.merge(params.permit(:service_name)) end end
步骤2:替换默认直传路由
在路由文件中优先声明自定义的直传路由,覆盖官方默认路由:
# config/routes.rb Rails.application.routes.draw do # 放在Active Storage默认路由之前 post '/rails/active_storage/direct_uploads', to: 'custom_direct_uploads#create' # 其他原有路由... end
步骤3:前端传递目标服务参数
修改表单的文件上传控件,新增data属性传递目标存储服务名,同时增加JS逻辑将参数带入直传请求:
<%= form.file_field :file, accept: 'image/jpeg', direct_upload: true, multipart: true, # 新增data属性传递目标服务名 data: { service_name: Rails.configuration.settings[:unsafe_files_service] } %>
增加前端监听逻辑,把服务名参数传入直传请求:
// 放在全局JS文件中即可 document.addEventListener('direct-upload:initialize', event => { const serviceName = event.target.dataset.serviceName if (serviceName) { event.detail.params = event.detail.params || {} event.detail.params.service_name = serviceName } })
验证方法
提交表单上传文件后,查看对应ActiveStorage::Blob记录的service_name字段,确认值为unsafe_files,同时检查对应S3桶内是否生成了对应文件即可。该方案兼容原有默认直传逻辑,未传递service_name参数的请求仍会使用默认的amazon存储服务。
内容的提问来源于stack exchange,提问作者beniutek
相关产品推荐
相关产品推荐

