角色和回形针,删除记录但不删除附件

问题描述 投票:6回答:6

我通常使用滑轨和回形针保存图像。

带有附件的记录被销毁时,附件也会从文件系统中删除。

99%的时间这是正确的操作,但是即使删除了db记录,在某些情况下我也需要将附件保留在系统中。

我想知道是否有人知道该怎么做。

我尝试过通过销毁记录之前通过update_attribute将附件字段设置为nil,但是update_attribute也会删除该文件。

一种方法是忽略所有回调,但是需要其他一些回调,这似乎有点过多。任何人都知道更好的方法...

干杯。

ruby-on-rails ruby image-processing callback paperclip
6个回答
3
投票

您可能想看看回形针中如何实现Attachment#assign(当您执行object.attachment = new_attachment时会调用)。基本上,它会进行一些设置,然后调用Attachment#clear,然后保存新文件。

Attachment#clear将旧文件放入删除队列中,当您再次调用save时,该文件将被处理,您想要的只是避免调用被清除,您可以通过编写新的assign方法跳过该行或通过猴子修补#clear使其变为无操作状态。从理论上讲,您可以将猴子修补在您希望发生这种情况的实例上,但是在我看来,您可能希望对整个项目都这样做。

或者您可以清除保存处理队列的实例变量。该变量没有访问器,但是执行instance_variable_get

应该很简单

1
投票

仅保留回形针生成的数据库字段(文件名,内容类型,文件大小)不会保留该文件。 destroy方法仍将通过索引指向它。

在销毁记录之前,请尝试将ID更改为某个随机数(例如999898)。如果抛出异常,则也将字段设为nil。这样,记录将不再指向文件,并在记录被销毁时保留。


1
投票

所以问题是怎么回事?您正在尝试实施撤消,以便有人可以删除然后取消删除吗?

我认为您的解决方案应处理“清除”标志,然后在清除标志为true的情况下每晚删除批处理作业。只要所有获取都用于带有索引的clear = false的记录,就不会影响性能。这个问题在解决方案中只是带有“错误”的感觉。只是提供了不同的视角。


1
投票

也许有点偏离主题:

[如果附件存储在S3上,则您可以覆盖has_attached_file方法,并且仅传递附件名称,而无需任何选项。在这种情况下,回形针会认为文件存储在文件系统中,只会删除任何内容。同样也没有例外。

我知道此解决方案可能有点笨拙/难看,但简单且可行。


1
投票

对我来说,覆盖Paperclip::Attachment#clear方法并不能解决问题。我必须重写Paperclip::Attachment#queue_all_for_delete

[正如Alex Falke所说,Paperclip具有:preserve_files选项,因此很显然,如果您想保留所有附件,可以使用它而不是覆盖它。

如果有特殊情况,改写#queue_all_for_delete是可行的方法,但是您必须有选择地这样做。猴子修补程序是全球性的,因此它不是最佳方法。我试图使用改进来限制猴子补丁的范围,但是词汇范围在我的用例中不能很好地发挥作用。

所以我最终得到了这个模块,该模块将自身注入方法查找路径,并有选择地为#queue_all_for_delete定义或取消定义无操作覆盖:

module PaperclipKeepAttachment
  def self.with_patch
    patch
    add_override
    yield
  ensure
    remove_override
  end

  def self.patch
    me = self
    Paperclip::Attachment.class_eval{ prepend me } unless Paperclip::Attachment.ancestors.include?(me)
  end

  def self.add_override
    define_method(:queue_all_for_delete) do
      # no-op
    end
  end

  def self.remove_override
    remove_method(:queue_all_for_delete)
  end
end

使用它,您可以执行以下操作:

PaperclipKeepAttachment.with_patch do 
  # The record will be destroyed but the attachment kept intact
  first_record.destroy
end

# The record will be destroyed and the attachment removed
second_record.destroy

1
投票

gem允许您进行软删除:

(来自paperclip

用于软删除的文件保留

一个选项可用于保留附件,以便在软删除的模型中正常播放。 (acts_as_paranoid,偏执狂等)

has_attached_file :some_attachment, {
    preserve_files: true,
}

这将防止在销毁模型时清除some_attachment,因此在以后恢复对象时它仍然存在。

© www.soinside.com 2019 - 2024. All rights reserved.