Rails 6.1中has_one_attached的service选项被忽略,附件上传默认S3桶如何解决?
问题原因及解决方案
核心原因
你遇到的是Ruby on Rails 6.1.0 ~ 6.1.3.2 版本的已知Active Storage功能缺陷:该版本区间内,has_one_attached/has_many_attached方法传入的附件级service参数优先级低于全局config.active_storage.service配置,所以会被全局配置覆盖。该问题已经在Rails 6.1.4版本被官方修复。
其他可能的触发场景
- 生产环境修改
storage.yml或模型代码后,没有重启Rails服务,旧配置仍在缓存中生效 ENV['AWS_LOGOS_BUCKET']环境变量配置错误,和全局桶的环境变量值完全一致- 使用Active Storage前端直接上传功能时,没有手动指定对应service,仍调用了全局service的上传接口
修复方案
方案1(推荐)
升级Rails版本到6.1.4或更高版本,升级后无需修改现有业务代码,模型层指定的service配置会自动覆盖全局配置。
方案2(临时兼容,无法升级Rails时使用)
新增初始化补丁文件config/initializers/active_storage_service_patch.rb,写入以下代码:
Rails.application.config.to_prepare do ActiveStorage::Attachment.class_eval do def service blob.service_name.present? ? ActiveStorage::Blob.services.fetch(blob.service_name) : ActiveStorage::Blob.service end end end
补丁添加后重启Rails服务即可生效。
验证检查项
修改生效后创建新的Logo附件记录,检查active_storage_blobs表对应记录的service_name字段值,正常情况下应该为amazon_logos_images而非默认的amazon。
内容的提问来源于stack exchange,提问作者Mateusz Urbański
相关产品推荐
相关产品推荐

