Search code examples
ruby-on-railsruby-on-rails-4amazon-s3carrierwavefog

How do I get Carrierwave to delete a file from S3?


I have a vanilla Carrierwave, Fog, S3 setup. Uploading to S3 is fine, but when I destroy the record in my rails console locally, or I delete from within my web app via a Delete link, it doesn't remove the file on S3.

In fact, this is what my log looks like:

Started DELETE "/posts/13" for 127.0.0.1 at 2014-08-30 04:19:39 -0500
Processing by PostsController#destroy as HTML
  Parameters: {"authenticity_token"=>"jcyevWU9M=", "id"=>"13"}
  Post Load (0.3ms)  SELECT  "posts".* FROM "posts"  WHERE "posts"."id" = $1 LIMIT 1  [["id", 13]]
  User Load (0.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
   (0.3ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["user_id", 1]]
   (0.2ms)  BEGIN
  Post Load (0.3ms)  SELECT "posts".* FROM "posts"  WHERE (("posts"."ancestry" ILIKE '13/%' OR "posts"."ancestry" = '13'))
  Role Load (0.2ms)  SELECT "roles".* FROM "roles"  WHERE "roles"."resource_id" = $1 AND "roles"."resource_type" = $2  [["resource_id", 13], ["resource_type", "Post"]]
  SQL (0.3ms)  DELETE FROM "posts" WHERE "posts"."id" = $1  [["id", 13]]
   (0.4ms)  COMMIT
Redirected to http://localhost:3000/posts
Completed 302 Found in 401ms (ActiveRecord: 2.2ms)

This is my file_uploader.rb file:

# encoding: utf-8

class FileUploader < CarrierWave::Uploader::Base
  storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "files/#{SecureRandom.uuid()}"
  end

  def extension_white_list
    %w(pdf)
  end
end

This is my Post.rb model file:

# == Schema Information
#
# Table name: posts
#
#  id         :integer          not null, primary key
#  status     :string(255)
#  title      :string(255)
#  photo      :string(255)
#  body       :text
#  created_at :datetime
#  updated_at :datetime
#  user_id    :integer
#  ancestry   :string(255)
#  file       :string(255)
#

class Post < ActiveRecord::Base
  has_ancestry
  belongs_to :user
  resourcify

  mount_uploader :photo, PhotoUploader
  mount_uploader :file, FileUploader
end

This is my delete action on my PostsController.rb:

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

I have never been able to get a file to be deleted from this S3 bucket with this AWS IAM user I created for this app.

What could be causing this?


Solution

  • The problem is with your uploader. You are using secure random for store dir.

    def store_dir
       "files/#{SecureRandom.uuid()}"
    end
    

    When carrierwave try to delete file, Then due to random value store_dir point to some other place. I am sure you also not able to display this file anywhere.

    So try something like this or something that is not randomly changes.

    def store_dir
      "files/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end