如何使用CarrierWave重新组织现有文件夹层次结构?

Oma*_*mar 9 reorganize ruby-on-rails-3 carrierwave

我正在尝试使用CarrierWave重新组织文件夹结构来移动我的S3存储桶中的文件.

我来到一个现有的Rails应用程序,其中一个类的所有图像都被上传到一个名为的文件夹中/uploads.如果两个用户使用相同的文件名上传不同的图像,则会导致问题,第二个图像会覆盖第一个图像.为了解决这个问题,我想重新组织文件夹,根据ActiveRecord对象实例将每个图像放在自己的目录中.我们CarrierWave用来管理文件上传.

旧的上传代码具有以下方法:

def store_dir
  "uploads"
end
Run Code Online (Sandbox Code Playgroud)

我修改了方法以反映我的新文件存储方案:

def store_dir
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
Run Code Online (Sandbox Code Playgroud)

这适用于新图像,但会破坏旧图像的URL.当我更改模型时,现有图像会立即将其URL报告在新文件夹中,而图像文件仍存储在其中/uploads.

> object.logo.store_dir
=> "uploads/object/logo/133"
Run Code Online (Sandbox Code Playgroud)

这是不正确的.此对象应报告其徽标/uploads.

我的解决方案是编写一个脚本来移动图像文件,但我没有在CarrierWave中找到正确的方法来移动文件.我的脚本看起来像这样:

MyClass.all.each |image|
  filename = file.name #This method exists in my uploader, returns the file name
  #Move the file from "/uploads" to "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end 
Run Code Online (Sandbox Code Playgroud)

我应该在脚本的第三行中将文件移动到新位置?

cga*_*gat 18

警告:这是未经测试的,因此在测试之前请不要在生产中使用.

这就是事情,一旦你改变'store_dir'的内容,你所有旧的上传都会丢失.你已经知道了.直接与S3交互似乎是最明显的解决方法,因为carrierwave没有移动功能.

可能有用的一件事是重新"存储"您的上传并更改'before:store'回调中的'store_dir'路径.

在您的上传器中:

#Use the old uploads directory so carriewave knows where the original upload is
def store_dir
  'uploads'
end

before :store, :swap_out_store_dir

def swap_out_store_dir
  self.class_eval do
    def store_dir
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后运行这样的脚本:

MyClass.all.each do |image|
  image.image.cache! #create a local cache so that store! has something to store
  image.image.store!
end
Run Code Online (Sandbox Code Playgroud)

在此之后,验证文件是否已复制到正确的位置.然后,您必须删除旧的上传文件.另外,删除上面的一次性使用上传代码并将其替换为新的store_dir路径:

def store_dir
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id} "
end
Run Code Online (Sandbox Code Playgroud)

我没有测试过这个,所以我不能保证它会起作用.请先使用测试数据查看是否有效,如果您有任何成功,请在此处发表评论.