11

我有一个带有avatar回形针的模型。它现在有一个简单的标准路径

has_attached_file :avatar,
  :path => "/:id-:style-:filename"

我需要进入一个模糊的

has_attached_file :avatar,
  :path => "/:id-:hash.:extension"
  :hash_secret => 'asecuresecret'

新图像一切正常,但是如何将存储在 S3 中的现有文件迁移到新的路径格式,即重命名它们?

我正在使用回形针 2.7 和 Rails 3.2

谢谢 !!!

4

3 回答 3

14

如果您只想使用 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,反之亦然。

于 2016-03-15T09:18:42.343 回答
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

一旦您确定新文件是正确的,则应手动删除原始文件或使用类似的任务。

于 2012-06-07T18:56:54.553 回答
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 文档,了解如何建立与您的 S3 帐户的连接。

于 2012-04-26T16:54:05.390 回答