如何让Carrierwave在销毁记录时删除文件?

55

我正在使用carrierwave宝石上传文件。

我已经建立了一个系统,允许用户标记不适当的图片,并允许管理员删除这些图片。根据我的观察,调用图片的destroy方法只会从数据库中删除路径名。

是否有一种方法可以让carrierwave实际上删除文件本身?或者当我删除图片路径时,Rails会自动删除文件?

3个回答

102

正如 @mu_is_too_short 所说,您可以使用 File#delete

这是一个代码片段,您可以在Rails应用程序中进行一些微调以使用作为辅助工具。

def remove_file(file)
  File.delete(file)
end

或者如果您只是在 file 中存储了文件名

def remove_file(file)
  File.delete("./path/to/#{file}")
end

7
File#delete和FileUtils.rm之间有什么区别? - Tall Paul
5
在2.2.2版本中,File.delete似乎会将文件名作为单独参数,并返回删除的文件数量的整数。如果发生错误会抛出异常。FileUtils.rm接受一个文件名列表或字符串,并可以传递选项,如 :force => true,它不会引发异常。 - oconn

62

不确定CarrierWave在这方面提供了什么,但您可以使用Ruby标准库中的FileUtils与ActiveRecord回调结合使用。

例如,

require 'FileUtils'
before_destroy :remove_hard_image

def remove_hard_image
  FileUtils.rm(path_to_image)
end

补充说明:这段代码是从记忆中获取的。


29
核心类中还有 File#delete 方法。 - mu is too short
3
如果你不想收到关于常量的各种警告,就需要使用require 'fileutils' - Samuel
使用宝石(gem)来处理像这样简单的事情,尤其是当标准库已经提供了此功能时,似乎是不必要的。对于File#delete,我给出+1的支持。 - yekta
哦,是啊。如果我没记错的话,我在文档中找不到它。感谢你指出来。 - yekta

1

如果想要删除文件,但不想指定完整的文件名,可以使用以下方法。

也可用于删除目录中特定扩展名的多个文件或所有文件...

file = Rails.root.join("tmp", "foo*") 

或者

file = Rails.root.join("tmp", ".pdf")  

files = Dir.glob(file) #will build an array of the full filepath & filename(s)
files.each do |f|
  File.delete(f)
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接