diff --git a/lib/tasks/active_storage.rake b/lib/tasks/active_storage.rake index 8766c1b4b..a803840f9 100644 --- a/lib/tasks/active_storage.rake +++ b/lib/tasks/active_storage.rake @@ -40,7 +40,11 @@ namespace :active_storage do model.find_each.each do |instance| 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( statement_name, [ @@ -48,7 +52,7 @@ namespace :active_storage do instance.send("#{attachment}_file_name"), instance.send("#{attachment}_content_type"), 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, "storage_#{attachment}", model.name, @@ -65,9 +69,11 @@ namespace :active_storage do name = attachment.name.delete_prefix("storage_") source = attachment.record.send(name).path - FileUtils.mkdir_p(File.dirname(dest)) - logger.info "Copying #{source} to #{dest}" - FileUtils.cp(source, dest) + if source && File.exist?(source) + FileUtils.mkdir_p(File.dirname(dest)) + logger.info "Copying #{source} to #{dest}" + FileUtils.cp(source, dest) + end end end end diff --git a/spec/lib/tasks/active_storage_spec.rb b/spec/lib/tasks/active_storage_spec.rb index f7150f41b..06ef03a41 100644 --- a/spec/lib/tasks/active_storage_spec.rb +++ b/spec/lib/tasks/active_storage_spec.rb @@ -29,6 +29,21 @@ describe "active storage tasks" do expect(storage_file_path(document)).to eq test_storage_file_paths.first 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 Dir.glob("#{storage_root}/**/*").select { |file_or_folder| File.file?(file_or_folder) } end