Rails and clip, delete the entry, but do not delete the attachment

I use rails and a paper clip to save images in the usual way.

When an entry with an attachment is destroyed, the attachment is also deleted from the file system.

In 99% of cases, this is the correct action, but there is a case when I need the application to remain on the system, even if the db record is deleted.

I was wondering if anyone knows how to do this.

I tried setting the attachment fields to nil via update_attribute before deleting the record, but update_attribute will also delete the file.

One way is to ignore all callbacks, however some of the other callbacks are necessary, and that seems too big. Anyone knows some better ways ...

Greetings.

+5
source share
6 answers

you can take a look at how Attachment#assign(called at runtime object.attachment = new_attachment) is implemented in a folder. Basically, it tweaks a bit, then calls Attachment#clear, then saves a new file.

# clear , , , , - , , , #clear, -op. , , , , .

, . , instance_variable_get

+3

- , (_, content_type, file_size), . destroy - .

(, 999898), . , . , .

+1

, , ? , - , ?

, "" , , . , , clear = false . "" . .

+1

, :

, S3 - has_attached_file - . Paperclip , . .

, /, .

+1

:

( paperclip)

Soft-Delete

, . (act_as_paranoid, ..)

has_attached_file :some_attachment, {
    :preserve_files => "true",
}

some_attachment, , , .

+1

Paperclip::Attachment#clear . Paperclip::Attachment#queue_all_for_delete.

, Paperclip :preserve_files, , , , .

, #queue_all_for_delete - , . , . , , .

So, I ended up with this module, which embeds itself in the method search path and selectively defines or cancels the no-op override for #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

With it you can do something like:

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
source

All Articles