11

I would like to set up a particular uploader so that when the related model object is destroyed the file on amazon s3 is not removed.

The reason for this is that my Upload model record although destroyed is still referenced within a second audit table.

I am using fog, carrierwave and s3.

Ben
  • 51,770
  • 36
  • 127
  • 149
nodrog
  • 3,532
  • 2
  • 25
  • 31

4 Answers4

15

Actually there is a way to do this, you just need to skip callback that deletes it:

skip_callback :commit, :after, :remove_<column_name>!

for example

# user.rb
mount_uploader :avatar
skip_callback :commit, :after, :remove_avatar!

see https://github.com/carrierwaveuploader/carrierwave#skipping-activerecord-callbacks

mkk
  • 7,583
  • 7
  • 46
  • 62
11

Well AFAIK remove_previously_stored_files_after_update only work when a model object is updated so setting it to false will not remove the old file during update

But in your case you have to ensure the file are still present when the related model object is destroy

well I dont think there(if you examine the code here) is any mechanism currently available in in Carrierwave do that

but you can overwritten the remove! to achieve the same I guess this involve setting up attr_accessor (which is flag to decide whether to keep the file or delete it)

Inside your desired Model define a attr_accessor (say keep_file)

and in the desired uploader override the remove! method

class MyUploader < CarrierWave::Uploader::Base 
  def remove!
     unless model.keep_file
       super
     end
  end
end

and ensure that you set the attr_accessor for the object (if you want to keep the deleted file) before destroying them

Example

u = User.find(10)
u.keep_file = true
u.destroy 

This will ensure that file are cleaned up when the record is deleted from database

Let me know if there any better to do this

Hope this help

Viren
  • 5,812
  • 6
  • 45
  • 98
10

Keeping files for all, or some uploaders

CarrierWave.configure do |config|
  config.remove_previously_stored_files_after_update = false
end

If you want to configure that on a per-uploaded basis:

class AvatarUploader < CarrierWave::Uploader::Base
  configure do |config|
    config.remove_previously_stored_files_after_update = false
  end

  ...
end
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • Thanks Dave, Unfortunately, i already had this, and its not working. Any thoughts on why it might fail, i have it in the uploader. – nodrog Jun 25 '13 at 16:49
  • @DaveNewton I dont think it will work It only work in case of update not deleting the record – Viren Jul 19 '13 at 19:26
0

I had a case where I needed my uploader to persist files not only upon uploading a new file, but also upon deletion of the record itself. I found that a mix of what Dave Newton and mkk have suggested above worked perfectly:

In my uploader I added:

class AttachmentUploader < CarrierWave::Uploader::Base
  configure do |config|
    config.remove_previously_stored_files_after_update = false
  end
end

Then on my model I added:

class Resource < ApplicationRecord
  # Skip the remove callback so the files remain upon deletion of the Resource record
  mount_uploader :attachment, AttachmentUploader
  skip_callback :commit, :after, :remove_attachment!
  ...
end
Jeff Sholl
  • 63
  • 6