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

填充数据库时单次附加图片正常,多次触发ActiveStorage::FileNotFoundError的原因

问题原因分析

你遇到的ActiveStorage::FileNotFoundError,核心问题出在重复使用了同一个已读取过的文件IO对象。

当第一次调用project.images.attach时,Active Storage会读取整个image_file的内容,这时候文件指针会移动到文件末尾(EOF位置)。第二次再用同一个image_file执行attach操作时,IO流已经没有可读取的内容了,Active Storage会判定这是一个空文件或无效文件,从而抛出这个错误。而单次附加正常,是因为只读取了一次文件,指针还没到末尾就完成了操作。

解决方案

这里有两种简单可行的修复方式:

方法1:每次attach时重新打开文件

把打开文件的操作放到循环内部,这样每次附加都会拿到一个全新的、指针在文件开头的IO对象:

# Add projects
1000.times do
  project = Project.new(
    name: Faker::Marketing.buzzwords.capitalize,
    description: Faker::Lorem.sentence(rand(1..30))
  )
  rand(1..3).times do
    # 每次循环都重新打开文件,保证IO指针在开头
    image_file = File.open("./db/seed_files/placeholder_image.png")
    project.images.attach(io: image_file, filename: "placeholder_image.png", content_type: "image/png")
  end
  project.save
end

方法2:重置文件指针到开头

如果不想频繁打开/关闭文件,可以在每次attach前用rewind方法把文件指针重置到开头:

# Add projects
1000.times do
  project = Project.new(
    name: Faker::Marketing.buzzwords.capitalize,
    description: Faker::Lorem.sentence(rand(1..30))
  )
  image_file = File.open("./db/seed_files/placeholder_image.png")
  rand(1..3).times do
    # 重置IO指针到文件开头,确保每次都能读取完整内容
    image_file.rewind
    project.images.attach(io: image_file, filename: "placeholder_image.png", content_type: "image/png")
  end
  project.save
  # 显式关闭文件,避免资源泄漏(Ruby会自动回收,但显式操作更规范)
  image_file.close
end

两种方法都能解决你的问题,第一种逻辑更直观,第二种减少了文件IO操作次数,性能上略优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:09:20