我使用Carrierwave有3个独立的模型将照片上传到S3。我一直在上传,这是存储照片在根S3存储桶的默认设置。于是我决定根据型号将它们存储在子目录如/替身,项目/等基于该模型他们从...上传
I am using Carrierwave with 3 separate models to upload photos to S3. I kept the default settings for the uploader, which was to store photos in a root S3 bucket. I then decided to store them in sub-directories according to model name like /avatars, items/, etc. based on the model they were uploaded from...
然后,我注意到,相同名称的文件已被覆盖,当我删除了一个模型记录,照片没有被删除。
Then, I noticed that files of the same name were being overwritten and when I deleted a model record, the photo wasn't being deleted.
因为我已经改变了store_dir从上传特定的设置是这样的:
I've since changed the store_dir from an uploader-specific setup like this:
def store_dir
"items"
end
到一个通用的其中一个存储在模型证件照片(我用蒙戈仅供参考):
to a generic one which stores photo under the model ID (I use mongo FYI):
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
下面谈到的问题。我想已经将所有的照片制作成S3到正确的目录中的S3。从我准备好了,S3没有目录本身。我在耙任务的麻烦。由于我改变了store_dir,Carrierwave正在寻找所有照片$ P $在错误的目录pviously上传。
Here comes the problem. I am trying to move all the photos already into S3 into the proper "directory" within S3. From what I've ready, S3 doesn't have directories per se. I'm having trouble with the rake task. Since i changed the store_dir, Carrierwave is looking for all the photos previously uploaded in the wrong directory.
namespace :pics do
desc "Fix directory location of pictures on s3"
task :item_update => :environment do
connection = Fog::Storage.new({
:provider => 'AWS',
:aws_access_key_id => 'XXXX',
:aws_secret_access_key => 'XXX'
})
directory = connection.directories.get("myapp-uploads-dev")
Recipe.all.each do |l|
if l.images.count > 0
l.items.each do |i|
if i.picture.path.to_s != ""
new_full_path = i.picture.path.to_s
filename = new_full_path.split('/')[-1].split('?')[0]
thumb_filename = "thumb_#{filename}"
original_file_path = "items/#{filename}"
puts "attempting to retrieve: #{original_file_path}"
original_thumb_file_path = "items/#{thumb_filename}"
photo = directory.files.get(original_file_path) rescue nil
if photo
puts "we found: #{original_file_path}"
photo.expires = 2.years.from_now.httpdate
photo.key = new_full_path
photo.save
thumb_photo = directory.files.get(original_thumb_file_path) rescue nil
if thumb_photo
puts "we found: #{original_thumb_file_path}"
thumb_photo.expires = 2.years.from_now.httpdate
thumb_photo.key = "/uploads/item/picture/#{i.id}/#{thumb_filename}"
thumb_photo.save
end
end
end
end
end
end
end
end
所以我在所有的食谱循环,寻找有照片的项目,确定老Carrierwave路径,试图用新的基础上,store_dir变化更新。我想,如果我只是更新为新路径photo.key,它会工作,但它不是。
So I'm looping through all the Recipes, looking for items with photos, determining the old Carrierwave path, trying to update it with the new one based on the store_dir change. I thought if I simply updated the photo.key with the new path, it would work, but it's not.
我是什么做错了吗?有没有更好的方式来完成的要求吗?
What am I doing wrong? Is there a better way to accomplish the ask here?
在这里,我就是这样做要得到这个工作...
namespace :pics do
desc "Fix directory location of pictures"
task :item_update => :environment do
connection = Fog::Storage.new({
:provider => 'AWS',
:aws_access_key_id => 'XXX',
:aws_secret_access_key => 'XXX'
})
bucket = "myapp-uploads-dev"
puts "Using bucket: #{bucket}"
Recipe.all.each do |l|
if l.images.count > 0
l.items.each do |i|
if i.picture.path.to_s != ""
new_full_path = i.picture.path.to_s
filename = new_full_path.split('/')[-1].split('?')[0]
thumb_filename = "thumb_#{filename}"
original_file_path = "items/#{filename}"
original_thumb_file_path = "items/#{thumb_filename}"
puts "attempting to retrieve: #{original_file_path}"
# copy original item
begin
connection.copy_object(bucket, original_file_path, bucket, new_full_path, 'x-amz-acl' => 'public-read')
puts "we just copied: #{original_file_path}"
rescue
puts "couldn't find: #{original_file_path}"
end
# copy thumb
begin
connection.copy_object(bucket, original_thumb_file_path, bucket, "uploads/item/picture/#{i.id}/#{thumb_filename}", 'x-amz-acl' => 'public-read')
puts "we just copied: #{original_thumb_file_path}"
rescue
puts "couldn't find thumb: #{original_thumb_file_path}"
end
end
end
end
end
end
end
也许不是$ P在世界$ pttiest的东西,但它的工作。
Perhaps not the prettiest thing in the world, but it worked.
您需要进行交互与S3对象直接移动至。你可能想看看 copy_object
和 delete_object
在雾的宝石,这就是CarrierWave用来与互动S3。
You need to be interacting with the S3 Objects directly to move them. You'll probably want to look at copy_object
and delete_object
in the Fog gem, which is what CarrierWave uses to interact with S3.
https://github.com/fog/fog/blob/8ca8a059b2f5dd2abc232dd2d2104fe6d8c41919/lib/fog/aws/requests/storage/copy_object.rb
https://github.com/fog/fog/blob/8ca8a059b2f5dd2abc232dd2d2104fe6d8c41919/lib/fog/aws/requests/storage/delete_object.rb