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

Angular前端上传文件至Rails+Dragonfly+OCI时保存失败问题

问题:Angular上传文件后,Rails中Dragonfly无法将文件上传至OCI对象存储

我在Angular中实现文件上传,将参数存入imageData和imageContent变量传给Rails后端。在Rails控制器中尝试用这些参数创建临时文件,并赋值给Dragonfly的logo访问器属性,但保存记录时,文件并未上传到OCI对象存储。不过在Rails控制台中直接测试OCI对象存储的上传功能是正常的。

Dragonfly访问器配置

dragonfly_accessor :logo do
  storage_options do |attachment|
    {
      path: "brand_logos/"
    }
  end
end

Rails控制器处理代码

decoded_data = Base64.decode64(params[:brand][:logo][:imageData]) # json parameter set in directive scope
file_name = params[:brand][:logo][:imagePath]
File.open(file_path, 'wb+') { |file| file.write(decoded_data) }
params[:brand][:logo][:tempfile] = file_path # json parameter set in directive scope

问题原因与修复方案

核心问题是你给Dragonfly的tempfile赋值的是文件路径字符串,但Dragonfly的文件访问器需要的是File对象(或实现IO接口的对象),而非路径字符串。

方案1:使用临时文件对象赋值

decoded_data = Base64.decode64(params[:brand][:logo][:imageData])
file_name = params[:brand][:logo][:imagePath]

# 创建带后缀的临时文件,避免格式识别问题
temp_file = Tempfile.new(
  [File.basename(file_name, '.*'), File.extname(file_name)],
  Rails.root.join('tmp')
)
temp_file.binmode
temp_file.write(decoded_data)
temp_file.rewind # 将文件指针移到开头,确保Dragonfly能读取完整内容

# 直接给模型属性赋值文件对象,无需修改params
@brand = Brand.new(params[:brand].except(:logo))
@brand.logo = temp_file
@brand.save!

# 清理临时文件
temp_file.close
temp_file.unlink

方案2:用StringIO替代物理文件(更高效)

不需要创建本地物理文件,直接用内存中的IO对象传递数据:

decoded_data = Base64.decode64(params[:brand][:logo][:imageData])
file_name = params[:brand][:logo][:imagePath]

# 用StringIO包装解码后的数据,模拟文件对象
file_io = StringIO.new(decoded_data)
# 给StringIO添加original_filename属性,满足Dragonfly的文件名要求
file_io.class.class_eval { attr_accessor :original_filename }
file_io.original_filename = file_name

@brand = Brand.new(params[:brand].except(:logo))
@brand.logo = file_io
@brand.save!

额外注意事项

  • 控制台能正常上传说明OCI存储配置无问题,问题集中在文件对象的传递逻辑上;
  • 使用Tempfile时要记得清理文件,避免服务器磁盘被临时文件占满;
  • StringIO方式无需磁盘IO,性能更优,推荐优先使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:40:23