We have already a working code for copying Carrierwave files from one model to another, however, it is only working for file based storage. For Amazon S3 storage, it is quite not working. Here is our old code:
def import_images(ad, image_uuids) imgs = [] transaction do asset_id = ad.asset_id image_uuids.each do |i| img = AssetImage.find_by(uuid: i, asset_id: asset_id) raise(Chuki::Forbidden, 'An asset image is not found') unless img begin imgs << img # Copy asset image to ad image create! ad: ad, image: img.image end if img end unless image_uuids.nil? end imgs end
Every time it hits the import method, it throws this error on our staging server:
ArgumentError (wrong number of arguments (given 1, expected 0)): carrierwave-aws (1.0.2) lib/carrierwave/storage/aws_file.rb:39:in `read' fastimage (2.0.0) lib/fastimage.rb:327:in `block in fetch_using_read'
I immediately suspect it is about the Amazon AWS storage, so I tested it locally and indeed, the issue is about cloud storage.
The fix is quite simple and it has been documented in Carrierwave wiki. Below is our new code.
def import_images(ad, image_uuids) imgs = [] transaction do asset_id = ad.asset_id image_uuids.each do |i| img = AssetImage.find_by(uuid: i, asset_id: asset_id) raise(Chuki::Forbidden, 'An asset image is not found') unless img begin imgs << img img.image.cache_stored_file! # Copy asset image to ad image create! ad: ad, image: img.image end if img end unless image_uuids.nil? CarrierWave.clean_cached_files! end imgs end
That’s it. Enjoy and share!