Vee
Vee

Reputation: 1841

Deleting Amazon S3 directory

I'm trying to delete an Amazon S3 directory after executing the destroy action on my controller.

controllers\videos_controller.rb:

def destroy
  @video = Video.find(params[:id])
  @video.destroy
  redirect_to videos_path, notice:  "The video #{@video.name} has been deleted."
end

models\video.rb:

after_destroy :remove_S3_directory

def remove_S3_directory
  path_to_be_deleted = "https://s3.amazonaws.com/bucket/uploads/video/attachment/(ID of the video)"
  FileUtils.remove_dir(path_to_be_deleted, :force => true)
end

How can I specify a path_to_be_deleted without hardcoding the path?

Upvotes: 0

Views: 919

Answers (2)

Vee
Vee

Reputation: 1841

I ended up installing Amazon's aws-sdk gem (carrierwave-sdk gem will also work in lieu of aws-sdk) and the using AWS delete_all method to remove all files based on a prefix. The format to use this method is as follows:

s3.buckets[ENV['AWS_BUCKET']].objects.with_prefix('uploads/video/attachment/1/').delete_all

Thus, I've put the following code in my controller:

def destroy
  @video = Video.find(params[:id])

  # Manipulating the string that points to the path under "bucket"
  directory_to_be_deleted = File.dirname(@video.attachment.url)
  bucket = ENV['AWS_BUCKET'] + '/'
  directory_to_be_deleted = directory_to_be_deleted.split(bucket)[1]
  directory_to_be_deleted = directory_to_be_deleted + '/'

  # Use Amazon APIs to remove directory
  s3 = AWS::S3.new(:access_key_id => ENV['AWS_KEY_ID'], :secret_access_key => ENV['AWS_KEY_VALUE'])
  s3.buckets[ENV['AWS_BUCKET']].objects.with_prefix(directory_to_be_deleted).delete_all

  @video.destroy
  redirect_to videos_path, notice:  "The video #{@video.name} has been deleted."
end

I suppose most of this code belongs in the model instead of the controller but it works so for now, I'm going to keep it as is.

Upvotes: 1

Shamsul Haque
Shamsul Haque

Reputation: 2451

Try in this way:-

In controllers\videos_controller.rb:

def destroy
  @video = Video.find(params[:id])
  vid = @video
  @video.destroy
  path_to_be_deleted = vid.attachment
  FileUtils.remove_dir(path_to_be_deleted, :force => true)
  redirect_to videos_path, notice:  "The video #{vid.name} has been deleted."
end

Upvotes: 0

Related Questions