我正试图播种我的开发数据库。其中一种模型Project
具有与之相关的图像。
我在./db/seed_files/
中放置了一个占位符图像。我的种子文件看起来像这样:
# 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")
project.images.attach(io: image_file, filename: "placeholder_image.png", content_type: "image/png")
project.save
end
运行正常。它将一个图像附加到每个项目。
但是,我想为每个项目添加多个图像。我以为可以多次粘贴同一张图片。
我尝试过:
# 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
project.images.attach(io: image_file, filename: "placeholder_image.png", content_type: "image/png")
end
project.save
end
但这会导致错误:ActiveStorage::FileNotFoundError
。
/Users/greidods/.rvm/gems/ruby-2.6.1/bundler/gems/rails-b366be3b5b28/activestorage/lib/active_storage/service/disk_service.rb:136:in `rescue in stream'
/Users/greidods/.rvm/gems/ruby-2.6.1/bundler/gems/rails-b366be3b5b28/activestorage/lib/active_storage/service/disk_service.rb:129:in `stream'
/Users/greidods/.rvm/gems/ruby-2.6.1/bundler/gems/rails-b366be3b5b28/activestorage/lib/active_storage/service/disk_service.rb:28:in `block in download'
/Users/greidods/.rvm/gems/ruby-2.6.1/bundler/gems/rails-b366be3b5b28/activesupport/lib/active_support/notifications.rb:180:in `block in instrument'
/Users/greidods/.rvm/gems/ruby-2.6.1/bundler/gems/rails-b366be3b5b28/activesupport/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
...
我觉得有一种方法可以为带有多个附件的行添加种子。
是什么导致此错误?为什么我可以附加一次图像但不能多次?
答案 0 :(得分:1)
我无法完全重现您的问题(我不断收到ActiveStorage::IntegrityError
异常而不是ActiveStorage::FileNotFoundError
),但我想我知道这是怎么回事。第一次附加图像后:
project.images.attach(io: image_file, filename: "placeholder_image.png", content_type: "image/png")
image_file
的当前位置将位于文件末尾。现在,当Active Storage尝试再次读取文件时,它将无法获取任何数据,因此校验和失败(我的IntegrityError
)或Active Storage认为那里没有文件(您的FileNotFoundError
)。 / p>
解决方案是通过调用#rewind
将文件位置重新设置为开头:
rand(1..3).times do
project.images.attach(io: image_file, filename: "placeholder_image.png", content_type: "image/png")
image_file.rewind
end
您可以在image_file.rewind
调用之前或之后project.images.attach
,快退刚打开的文件并没有任何意义。您传递给#rewind
的{{1}}并不总是支持io
(或需要),因此Active Storage不能真正做到这一点。
或者,您可以在每次迭代时打开文件:
#attach
我假设您的问题中rand(1..3).times do
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
所缺少的do
只是一个错字BTW。
答案 1 :(得分:0)
我通过简单地使用数组作为参数来实现它:
image_file = File.open("./db/seed_files/placeholder_image.png")
files = []
rand(1..3).times do
files << {io: image_file,
filename: "placeholder_image.png",
content_type: "image/png"
}
project.images.attach(files)
end