我有一个带有avatar
回形针附件的模型。它现在有一个简单的标准路径
has_attached_file :avatar,
:path => "/:id-:style-:filename"
我需要进入一个混淆的
has_attached_file :avatar,
:path => "/:id-:hash.:extension"
:hash_secret => 'asecuresecret'
新图像的一切正常,但如何将存储在S3中的现有文件迁移到新的路径格式,即重命名它们?
我正在使用paperclip 2.7和Rails 3.2
谢谢!!!
答案 0 :(得分:13)
如果您只想使用Paperclip而且您不担心重新上传,我会采用其他方法。
假设您有以下内容:
class User
has_attached_file :image, path: "/:old_path/:filename"
...
end
并且您希望迁移到新路径:"/:new_path/:filename"
我的建议是使用旧路径创建FakeUser
并在用户模型中更改它。
class FakeUser
self.table_name = :users
has_attached_file :image, path: "/:old_path/:filename"
...
end
class User
has_attached_file :image, path: "/:new_path/:filename"
...
end
您现在可以编写以下迁移:
FakeUser.find_each do |fake_user|
User.find(fake_user.id).update(image: fake_user.image)
fake_user.image.destroy
end
然后,您可以在迁移完成后删除FakeUser模型。
顺便说一句,这种方法也可以完美地从本地文件系统迁移到S3,反之亦然。
答案 1 :(得分:4)
这个rake任务应该可以解决问题。我用aws-sdk 1.5.2和ruby 1.9.3p194尝试了它。
new_key
应映射到您的新回形针路径。不要忘记根据您的需要设置:acl
。
namespace :data do
desc 'aws images migration'
task :migrate_images do |t, args|
s3 = AWS::S3.new(:access_key_id => 'XXX', :secret_access_key => 'XXX')
bucket = s3.buckets['your-bucket-name']
bucket.objects.each do |object|
new_key = object.key.gsub(........)
new_object = bucket.objects[new_key]
object.copy_to new_object, {:acl => :public_read}
end
end
end
一旦确定新文件正确,就应手动删除原始文件或使用类似任务删除原始文件。
答案 2 :(得分:0)
我会写一个rake任务(或者只是一个普通的脚本,如果你愿意,可以在rails上下文中运行)。如果您正在使用aws-s3 gem,请迭代您知道它们具有旧路径格式的模型实例,或尝试在文件名上写一些条件以匹配它们,并逐个移动。
Model.find_in_batches(:batch_size => 500,
:conditions => "avatar_filename like 'SOMETHING_MATCHING'") do |o|
AWS::S3::S3Object.rename(old_path(o.avatar), o.avatar.url, 'BUCKET_NAME')
end
如果您已使用新路径定义配置了头像,请编写一个可以根据头像属性构建旧路径的方法。
您可以阅读aws-s3 gem文档here,了解如何建立与S3帐户的连接。