Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I dynamically set preserve_files option from a Paperclip file?

At my project, I'm using Paperclip together with Paranoia gem (in order to soft-delete some models). At this model, I use both gems together:

class Material < ActiveRecord::Base
    has_attached_file :material, preserve_files: true

    acts_as_paranoid

    validates_attachment :material, presence: true
end

The Paranoia gem offer a method to hard-delete the object: the really_destroy! method. But, when I call this method, the object is deleted but the file is preserved. What I what is delete the file too. Example:

@material_a.destroy # soft-delete the object and preserve the file
@material_b.really_destroy! # hard-delete the object and delete the file

Is there any way to dynamically set the Paperclip preserve_files option?

like image 723
Felipe Coutinho Avatar asked Nov 21 '14 13:11

Felipe Coutinho


1 Answers

It seems you can't dynamically set the :preserve_files option, but there's another way to do what you want.

Paperclip deletes attachments by first setting up a queue of paths to delete, and then deleting them when you save the object. An object can have multiple paths to delete if there are multiple styles of the same object (e.g. different sizes of an image file). If you call #destroy or #clear (without arguments), it'll call #queue_all_for_delete, which checks whether :preserve_files is set. But if you call #clear with a list of styles to delete, it'll call #queue_some_for_delete, which doesn't check :preserve_files.

So, we just have to provide #clear with a list of all the styles:

all_styles = @material_b.attachment.styles.keys.map { |key|
    @material_b.attachment.styles[key].name
} << :original
@material_b.attachment.clear(*all_styles)
@material_b.save
@material_b.really_destroy!
like image 167
Michael Keenan Avatar answered Sep 28 '22 11:09

Michael Keenan