Carrierwave - destroy object only after it has been deleted from my storage

4

Carrierwave only deletes the 'mounted' file after the object in the database has been removed:

after_commit :remove_avatar! :on => :destroy

link

I'm implementing a BackgroundDestroyable concern and for this I have a worker deleting the files.

The deleted_at field registers when the object was marked for complete removal and to ensure that objects are only actually removed by the worker I needed to reset the destroy on concern.

If one of the workers receives a timeout I lose the reference of my orphaned files in S3, since my objects in the database have been deleted.

What should I do to make sure I will not be orphaned in S3? Call remove_avatar! direct before object.destroy and then skip_callback?

Is it safe to do this?

    
asked by anonymous 13.03.2014 / 22:24

2 answers

1

What I did was call remove_avatar! before calling super() and actually doing the removal, without changing anything in the callbacks.

For registration, follow the code of concern:

# BackgroundDestroyable classes MUST have deleted_at:datetime column
module BackgroundDestroyable
  extend ActiveSupport::Concern

  included do
    default_scope { where(deleted_at: nil) }
    scope :deleted, -> { unscoped.where.not(deleted_at: nil) }
  end

  def destroy(mode = :background)
    if mode == :background
      unless self.deleted_at.present?
        update_attribute :deleted_at, Time.now
        Resque.enqueue(BackgroundDestroyer, self.id, self.class.to_s)
      end
    elsif mode == :now
      self.class.uploaders.each do |uploader, uploader_class|
        self.send("remove_#{uploader}!")
      end
      super()
    end
  end

  def destroy_now!
    self.destroy(:now)
  end
end
    
01.04.2014 / 21:26
0

For me, it makes more sense to call remove_avatar! before calling object.destroy . So you always have the assurance that you will not have any orphaned objects in S3, checking to see if the object has actually been removed.

I'd rather not mess with callbacks, unless I know exactly what I'm doing. Also, I always prefer to leave explicit behavior in the code and callbacks are not very explicit. And from experience, you will thank yourself very much in a couple of months when you need to look at this script and do some maintenance on it.

    
21.03.2014 / 22:09