Closed simptive closed 10 months ago
Please provide more details, like your uploader and related implementation. Obviously a deleted file is expected to be removed from the disk, so it'll be a bug in your app or possibly CarrierWave.
My implementation is a bit complex but I hope you'll get it. Here's my photograph_uploader.rb:
class HRM::PhotographUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
before :process, :validate
process resize_to_fill: [255,300], convert: :jpg, interlace: :plane
def store_dir
"storage/#{model.class.to_s.underscore}/#{mounted_as}"
end
def default_url(*args)
ActionController::Base.helpers.asset_path("user-default.jpg")
end
def extension_allowlist
%w(jpg jpeg png)
end
def content_type_allowlist
[/image\//]
end
def validate(file)
begin
image = MiniMagick::Image.open(file.path)
rescue
raise "Image format isn't valid"
end
end
def filename
@name ||= "#{Digest::SHA1.hexdigest("#{Time.now.to_i}#{file.original_filename}")}.#{file.extension.downcase}" if original_filename
end
end
Relevant Model:
class HRM::Employee < HRM::HrmRecord
mount_uploader :photograph, HRM::PhotographUploader
end
Controller:
class Hrm::EmployeesController < ApplicationController
before_action -> { set_attachment_params(params[:emp],:photograph) }, only: [:create,:update,:save_photograph]
def save_photograph
@emp.update!(photograph: params[:emp][:photograph])
redirect_back(fallback_location: authenticated_root_path)
end
def set_attachment_params(obj_params,attr)
# '1' mean current attachment should be preserved,
# '0' mean delete it, otherwise new attachment will be saved.
return unless obj_params
if obj_params['0'] # array of objects
obj_params.each{|i,h| set_attachment_params(h,attr) }
else
obj_params.delete(attr) if obj_params[attr] == '1'
end
end
end
View:
<%= image_view _class: "photograph editable #{_class}", path: value, width: img_width, height: img_height do %>
<%= file_field obj, field, accept: ".png, .jpg, .jpeg" %>
<%# Current Photo preserved flag. Below element will be deleted if photo is changed. %>
<%= hidden_field obj, field, value: '1', class: 'preserve-photo' %>
<%= button_tag type: 'button', class: 'btn btn-danger btn-flat btn-sm remove-photo', data: {avatar: avatar } do %>
<i class="fa fa-trash"></i>
<% end %>
<%= label obj, field, class: 'btn btn-info btn-flat btn-sm' do %>
<i class="fa fa-folder-open"></i>
<% end %>
<% end %>
The issue you're having could be this one: https://github.com/carrierwaveuploader/carrierwave/issues/2713 Could you try the master branch, as the fix is not released yet?
You're right. Tried master branch (3.0.5 d27c987) and the issue is gone.
I was using carrierwave 2.2.0 in rails 7.1.1. When a file is replaced or deleted, corresponding file was also overwrite / deleted from the disk. After migrating to 3.0, old files are kept on disk no matter file was deleted (params {:file => nil}) or replaced with other file by the user. I suspect from the documentation that carrierwave will no longer be deleting files and rather promoting explicit destroy method but it's not clear from the documentation. Please clear if you have insights.