Ignore deleted files in Active Storage migration

Files might be missing for whatever reason or records might not point to
any files; in these edge cases, we were getting an exception.
This commit is contained in:
Javi Martín
2021-07-27 01:06:37 +02:00
parent 038fb76896
commit 7330bfb6ae
2 changed files with 26 additions and 5 deletions

View File

@@ -40,7 +40,11 @@ namespace :active_storage do
model.find_each.each do |instance| model.find_each.each do |instance|
attachments.each do |attachment| attachments.each do |attachment|
next if instance.send(attachment).path.blank? source = instance.send(attachment).path
next if source.blank?
file = File.read(source) if File.exist?(source)
connection.exec_prepared( connection.exec_prepared(
statement_name, [ statement_name, [
@@ -48,7 +52,7 @@ namespace :active_storage do
instance.send("#{attachment}_file_name"), instance.send("#{attachment}_file_name"),
instance.send("#{attachment}_content_type"), instance.send("#{attachment}_content_type"),
instance.send("#{attachment}_file_size"), instance.send("#{attachment}_file_size"),
Digest::MD5.base64digest(File.read(instance.send(attachment).path)), file && Digest::MD5.base64digest(file) || SecureRandom.hex(32),
instance.updated_at.iso8601, instance.updated_at.iso8601,
"storage_#{attachment}", "storage_#{attachment}",
model.name, model.name,
@@ -65,9 +69,11 @@ namespace :active_storage do
name = attachment.name.delete_prefix("storage_") name = attachment.name.delete_prefix("storage_")
source = attachment.record.send(name).path source = attachment.record.send(name).path
if source && File.exist?(source)
FileUtils.mkdir_p(File.dirname(dest)) FileUtils.mkdir_p(File.dirname(dest))
logger.info "Copying #{source} to #{dest}" logger.info "Copying #{source} to #{dest}"
FileUtils.cp(source, dest) FileUtils.cp(source, dest)
end end
end end
end
end end

View File

@@ -29,6 +29,21 @@ describe "active storage tasks" do
expect(storage_file_path(document)).to eq test_storage_file_paths.first expect(storage_file_path(document)).to eq test_storage_file_paths.first
end end
it "migrates records with deleted files ignoring the files" do
document = create(:document,
attachment: nil,
paperclip_attachment: File.new("spec/fixtures/files/clippy.pdf"))
FileUtils.rm(document.attachment.path)
run_rake_task
document.reload
expect(ActiveStorage::Attachment.count).to eq 1
expect(ActiveStorage::Blob.count).to eq 1
expect(document.storage_attachment.filename).to eq "clippy.pdf"
expect(test_storage_file_paths.count).to eq 0
end
def test_storage_file_paths def test_storage_file_paths
Dir.glob("#{storage_root}/**/*").select { |file_or_folder| File.file?(file_or_folder) } Dir.glob("#{storage_root}/**/*").select { |file_or_folder| File.file?(file_or_folder) }
end end