I cant figure out how to update/rename a file uploaded/managed with Carrierwave-mongoid in rails 3.2.6. I want to rename the file in the db as well as on the filesystem.
Something like this maybe...
def rename( id , new_name )
f = UploadedFile.find(id)
if f.update_attributes({ f.file.original_filename: new_name }) # this is WRONG, what is right???
new_path = File.join( File.dirname( f.file.current_path ) , new_name ))
FileUtils.mv( f.file.current_path , new_path )
end
return f
end
Let me add this is after it has been uploaded already.
I was able to get the following working, although I'm sure there is a more elegant way. I'd appreciate any comments on the following
*add this to app/uploaders/file_uploader.rb
def rename(new_name)
sf = model.file.file
new_path = File.join( File.dirname( sf.file ) , "#{new_name}#{File.extname( sf.file )}")
new_sf = CarrierWave::SanitizedFile.new sf.move_to(new_path)
model.file.cache!(new_sf)
model.save!
return model
end
Thanks!
The most efficient way to do this is to just move the existing S3 object (assuming your storage layer is S3):
def rename(new_name)
bucket_name = "yourapp-#{Rails.env}"
resource = Aws::S3::Resource.new
bucket = resource.bucket(bucket_name)
object = bucket.object(path)
new_filename = "#{new_name}#{File.extname(path)}"
new_path = File.join(File.dirname(path), new_filename)
object.move_to(bucket: bucket_name, key: new_path)
model.update_column(mounted_as, new_filename)
model.reload
# Now call `recreate_versions!(*versions.keys)`
# if you want versions updated. Explicitly passing
# versions will prevent the base version getting
# reuploaded.
model
end
This is using the aws-sdk-s3
gem.
I store image files -- and derivative versions -- in an S3-compatible solution. I use Carrierwave (1.2.2) with the "fog-aws" gem (3.0.0) on Rails 5.1. The following public method works for me when added to the "uploader" file (eg, app/uploaders/example_uploader.rb
):
class ExampleUploader < CarrierWave::Uploader::Base
<snip>
# Renames original file and versions to match given filename
#
# Options:
# * +:keep_original+ - Do not remove original file and versions (ie, copy only)
def rename(new_filename, options = {})
return if !file || new_filename == file.filename
target = File.join(store_path, new_filename)
file.copy_to(target)
versions.keys.each do |k|
target = File.join(store_path, "#{k}_#{new_filename}")
version = send(k).file
version.copy_to(target)
end
remove! unless options[:keep_original]
model.update_column(mounted_as, new_filename) && model.reload
end
<snip>
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With