【问题标题】:Preventing Paperclip from deleting/overwriting attachments on update防止回形针在更新时删除/覆盖附件
【发布时间】:2011-02-06 02:45:40
【问题描述】:

我很难弄清楚如何防止 Paperclip 删除旧版本的附件(图像)。

我有一个模型 Site,它有一个附件徽标。我想保留旧徽标,因为我将跟踪模型的更改并希望查看徽标的历史记录。

我正在跟踪另一个模型中的更改,该模型引用了文件路径。我的问题是,当使用新徽标更新网站时,Paperclip 会先刷新旧徽标。

令我惊讶的是,在创建新附件之前,您无法切换选项以防止 Paperclip 刷新旧附件。

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 paperclip


    【解决方案1】:

    有一个新选项告诉回形针保留旧附件:

    https://github.com/thoughtbot/paperclip/commit/65e8d4f6de50732d8e1b https://github.com/thoughtbot/paperclip/issues/60

    使用简单:

    has_attached_file => :attachment,
                         :styles => { :thumb => 100x100! },
                         :preserve_files => true
    

    它还没有记录,需要一些挖掘才能找到,所以我想在这里分享它。

    【讨论】:

    • 谢谢。从这里 +1,即使你当时没有解决我的问题。
    • 截至今天,preserve_files 似乎已被弃用,对于最新的回形针 API:rubydoc.info/gems/paperclip/Paperclip/… 请参阅 keep_old_files:保持现有附件文件(原始文件 + 调整大小)不会在附件被删除时自动删除清除或更新。默认为假。
    • @AdrienSchuler 我认为这两者是分开的。即使父记录被删除,preserve_files 也会保留文件,而keep_old_files 不提供此保证。
    • 是否有人注意到Paperclip 在销毁时仍将所有附件属性设置为nil?这使得仅清除deleted_at 属性来恢复记录变得困难,因为所有重要属性都设置为nil
    • 是否有任何解决方案可以避免回形针将这些属性设置为 NIL ? @JoshuaPinter
    【解决方案2】:

    因为附件是在类级别定义的,Paperclip 使用它自己的插值库来插值字符串中的符号。您可以使用此库创建自己的插值。

    我会在模型中添加一个名为attachment_version 或类似名称的字段,然后在每次更改文件时递增此版本号。然后,在初始化文件中为它创建一个插值:

    Paperclip.interpolates :version do |attachment, style|
      attachment.instance.attachment_version
    end
    

    现在您可以在字符串中使用:version

    class Model < ActiveRecord::Base
      has_attached_file :something, :path => " :rails_root/public/somethings/etc/:version.:extension"
    end
    

    更多信息请参见the wiki documentation

    [更新]

    经过一番挖掘(请参阅此答案的 cmets),我得出的结论是,由于 Paperclip::Atachment#attach 中调用的代码,Paperclip 仍将删除旧附件。处理这个问题的最好方法可能是基于Paperclip::Storage::Filesystem 创建一个新的存储引擎并覆盖#flush_deletes。请注意,该方法无法判断文件是否因为它所属的模型被删除而排队等待删除,或者正在上传新文件。

    【讨论】:

    • 我突然想到 Paperclip 可能仍然会删除旧文件,只是默认情况下,即使名称不匹配......
    • 看来是这样。 Paperclip::Attachment#assign 调用 #clear,后者调用 queue_existing_for_delete,而后者又完全按照听起来的样子。您可以基于github.com/thoughtbot/paperclip/blob/master/lib/paperclip/…创建一个新的存储引擎,并根据需要修改#flush_deletes
    • 感谢 BinaryMuse,这似乎是目前最好的方法。你应该创建一个答案;-)
    【解决方案3】:

    lib/paperclip_monkey_patch.rb:

    module Paperclip
      class Attachment
       def clear
        # nop
        #raise "hell"
        # op
        instance_write(:file_name, nil)
        instance_write(:content_type, nil)
        instance_write(:file_size, nil)
        instance_write(:updated_at, nil)
      end
     end
    end
    

    然后将这一行添加到删除附件的任何文件的顶部:

    需要'paperclip_monkey_patch'

    感谢Ruby Forum

    【讨论】:

      【解决方案4】:

      去年夏天在 Rails 博客上工作时,我遇到了与 Paperclip 附件类似的问题。

      有一个补丁可以解决这个问题。我无法让它为自己工作,但值得一试!

      http://github.com/alainravet/paperclip/tree/keep_old_files

      【讨论】:

        猜你喜欢
        • 2016-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多