Carrierwave, creating a duplicate attachment when

2020-02-06 05:55发布

问题:

I would like to duplicate a model. The original model contains an attachment through Carrierwave. Ideally, a new attachment would be created, that is a copy of the original image, for the new model object.

I have looked through the Carrierwave documentation, and googled this problem, but have not found a solution that creates a new duplicate of the original image. Is this reasonable? Possible?

回答1:

I don't believe Carrierwave has this option. However, you can make use of the *_remote_url= method to set the new model's picture to be a duplicate of the first.

Here's a brief example

Say I have a model which has_one :photo attached with carrierwave. I can duplicate, the model, set the photo to the previous one and save it. Example:

first_model = User.first
duplicate_model = first_model.dup #(where the dup code duplicates everything else you need)
duplicate_model.remote_photo_url = first_model.photo_url
duplicate_model.save

This would then "copy" the photo from the first object into your second as a new carrierwave attachment.



回答2:

While copy_carrierwave_file is a neat gem it is not nescessary as long as you use local storage.
carrierwave can use local files as source of attachments and you can use this to duplicate the attachment:

first_user = User.first
duplicate_user = first_user.dup
duplicate_user.photo = File.open(first_user.photo.file.file) if first_user.photo.present?
duplicate_user.save

This is more efficient than routing the image twice through your web server.



回答3:

Try this gem https://github.com/equivalent/copy_carrierwave_file , it handles both local storage and Fog storage

original_resource = User.last
new_resource      = User.new

CopyCarrierwaveFile::CopyFileService.new(original_resource, new_resource, :avatar).set_file    

new_resource.save
nev_resource.avatar.url # https://...image.jpg


回答4:

For me with CarrierWave 0.10 this works just fine:

user = User.first
dup_user = user.dup
dup_user.photo = user.photo
dup_user.save

Although I'm not sure how this works out when using cloud storage like S3