How to update/rename a carrierwave uploaded file?

后端 未结 6 1328
我在风中等你
我在风中等你 2021-02-04 20:30

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.

<
相关标签:
6条回答
  • 2021-02-04 20:55

    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.

    0 讨论(0)
  • 2021-02-04 21:08

    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!

    0 讨论(0)
  • 2021-02-04 21:09

    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
    
    0 讨论(0)
  • 2021-02-04 21:12

    I did this with this way:

      def filename
        if !cached? && file.present?
          new_filename = 'foobar'
          new_path = File.join(File.dirname(file.path), new_filename)
          file.move_to(new_path)
          recreate_versions!
          new_filename
        else
          super
        end
      end
    

    I think this is only right way to rename file.

    0 讨论(0)
  • 2021-02-04 21:17

    I used this rake task for reprocessing uploaded images after modifying version settings (filename and image size) in my uploader file:

    # Usage: rake carrierwave:reprocess class=Model
    namespace :carrierwave do
      task :reprocess => :environment do
    
        CLASS = ENV['class'].capitalize
        MODEL = Kernel.const_get(CLASS)
        records = MODEL.all
    
        records.each do |record|
          record.photo.recreate_versions! if record.photo?
        end
    
      end
    end
    

    Notes:

    • Replace "photo" with whatever you named your uploader.
    • Rake tasks go in the lib/tasks folder.
    • This is using Active Record, not sure if Mongoid needs something different.
    0 讨论(0)
  • 2021-02-04 21:19

    Based on @user892583, I worked on it and came up with a simpler solution:

    def rename!(new_name)
      new_path = File.join(File.dirname(file.file), new_name)
      file.move_to(new_path)
    end
    
    0 讨论(0)
提交回复
热议问题