ruby-on-railsrails-activestorage

Rails ActiveStorage: How to delete all variants of a specific Attachment completely (all ActiveStorage DB records AND files, except for the original)


How do I delete all variants (but not the original upload) of a specific Attachment completely, meaning:

The model scenario is: Avatar has_one_attached :file

I have tried...

ActiveStorage::VariantRecord.where(blob_id: @avatar.file.blob.id).destroy_all

...but this does apparently NEITHER delete entries in the table active_storage_blobs NOR their associated files in the folder /storage.

(Context: I need to destroy the "old" variants before they are recreated from the original uploaded file, because Rails does apparently not replace the "old" ones automatically.)


Solution

  • Simply call ActiveStorage::Attached::One#purge on given attachment

    @avatar.file.purge
    

    This directly purges the attachment (i.e. destroys the blob and attachment with all variants and deletes the files on the service).

    The complete list of steps could then look like this:

    # 1. Collect data of the original file
    image_io =     @avatar.file.download
    content_type = @avatar.file.content_type
    filename =     @avatar.file.filename.to_s
    
    # 2. Purge all DB records/files/variants of the original file
    @avatar.file.purge
    
    # 3. Create a copy of the original file
    new_blob = ActiveStorage::Blob.create_and_upload!(
      io: StringIO.new(image_io),
      filename: filename,
      content_type: content_type
    )
    
    # 4. Attach the new file
    @avatar.file.attach(new_blob)
    
    # 5. Create the variants of the new file
    #  [...]