如何清理开发环境的ActiveStorage记录和存储文件夹?

twn*_*ing 11 ruby-on-rails rails-activestorage

根据Rails(edge6.0)指南,我们可以通过分别调用以下语句来对系统测试集成测试中使用的ActiveStorage进行维护工作

  # System Test
  FileUtils.rm_rf("#{Rails.root}/storage_test")

  # Integration Test
  FileUtils.rm_rf(Rails.root.join('tmp', 'storage'))
Run Code Online (Sandbox Code Playgroud)

我想知道 -

是否有任何 Rails 内置函数或 rake 命令或 gem 可以执行以下操作?

  1. 删除孤立 blob(ActiveStorage::Blob不再与任何ActiveStorage::Attachment记录关联的记录)
  2. 删除孤立文件(不再与任何ActiveStorage::Blob记录关联的文件)

我没有看到任何相关的 rake 任务rails --tasks

目前,我正在使用

# remove blob not associated with any attachment
ActiveStorage::Blob.where.not(id: ActiveStorage::Attachment.select(:blob_id)).find_each do |blob|
  blob.purge # or purge_later
end
Run Code Online (Sandbox Code Playgroud)

这个脚本用于清理孤立文件(通过rails console

# run these ruby statement in project rails console
# to remove the orphan file
include ActionView::Helpers::NumberHelper

dry_run = true
files = Dir['storage/??/??/*']

orphan = files.select do |f|
  !ActiveStorage::Blob.exists?(key: File.basename(f))
end

sum = 0
orphan.each do |f|
  sum += File.size(f)
  FileUtils.remove(f) unless dry_run
end

puts "Size: #{number_to_human_size(sum)}"
Run Code Online (Sandbox Code Playgroud)

est*_*ani 10

ActiveStorage::Blob.unattached.each(&:purge_later)
Run Code Online (Sandbox Code Playgroud)

或者只是purge如果您不希望它在后台发生。


dft*_*dft 2

现在有一种更简单的方法,不确定它何时改变,但有一个警告(它会留下空文件夹):

# rails < 6.1
ActiveStorage::Blob.left_joins(:attachments).where(active_storage_attachments: { id: nil }).find_each(&:purge)

# rails >= 6.1
ActiveStorage::Blob.missing(:attachments).find_each(&:purge)
Run Code Online (Sandbox Code Playgroud)

这将删除数据库中的记录并删除磁盘上的物理文件,但保留文件所在的文件夹。