将上传的文件从Active Storage迁移到Carrierwave

时间:2019-09-27 00:23:03

标签: ruby-on-rails carrierwave rails-activestorage

出于各种原因,我将上传的文件从ActiveStorage(AS)迁移到CarrierWave(CW)。

我正在执行rake任务并整理出逻辑-我很困惑如何将AS Blob馈入CW文件。

我正在尝试类似这样的事情:

@files.each.with_index(1) do | a, index |

  if a.attachment.attached?

    a.attachment.download do |file|
      a.file = file
    end
    a.save!

  end

end      

这是基于以下两个链接:

https://edgeguides.rubyonrails.org/active_storage_overview.html#downloading-files

message.video.open do |file|
  system '/path/to/virus/scanner', file.path
  # ...
end

https://github.com/carrierwaveuploader/carrierwave#activerecord

# like this
File.open('somewhere') do |f|
  u.avatar = f
end

我在本地进行了测试,并且文件未通过上传器挂载。我的问题是:

  • 我在这里错过了明显的东西吗?
  • 我的方法有误,需要一种新方法吗?

奖金K问题:

  • 这样做时,似乎看不到设置CW文件名的清晰路径吗?

2 个答案:

答案 0 :(得分:1)

file块获得的attachment.download对象是一个字符串。更准确地说,来自.download的响应是文件,“以块的形式流化并产生”(请参见documentation)。我通过调用file.class来确认班级是否符合我的期望。

因此,要解决您的问题,您需要提供一个可以调用.read的对象。通常,这是使用Ruby StringIO类完成的。

但是,考虑到Carrierwave also expects a filename,您可以使用继承了StringIO的帮助程序模型来解决它(来自上面链接的博客文章):

class FileIO < StringIO
  def initialize(stream, filename)
    super(stream)
    @original_filename = filename
  end

  attr_reader :original_filename
end

然后您可以将a.file = file替换为a.file = FileIO.new(file, 'new_filename')

答案 1 :(得分:1)

这是我最后的任务(根据公认的答案)-可以进行调整。对我有用吗?

namespace :carrierwave do
  desc "Import the old AS files into CW"
  task import: :environment do

    @files = Attachment.all

    puts "#{@files.count} files to be processed"
    puts "+" * 50

    @files.each.with_index(1) do | a, index |

      if a.attachment.attached?

        puts "Attachment #{index}:  Key: #{a.attachment.blob.key} ID: #{a.id} Filename: #{a.attachment.blob.filename}"

        class FileIO < StringIO
          def initialize(stream, filename)
            super(stream)
            @original_filename = filename
          end

          attr_reader :original_filename
        end

        a.attachment.download do |file|
           a.file = FileIO.new(file, a.attachment.blob.filename.to_s)
        end
        a.save!
        puts "-" * 50

      end

    end

  end

  desc "Purge the old AS files"
  task purge: :environment do

    @files = Attachment.all

    puts "#{@files.count} files to be processed"
    puts "+" * 50


    @files.each.with_index(1) do | a, index |

      if a.attachment.attached?

        puts "Attachment #{index}:  Key: #{a.attachment.blob.key} ID: #{a.id} Filename: #{a.attachment.blob.filename}"
        a.attachment.purge
        puts "-" * 50
        @count = index

      end

    end

    puts "#{@count} files purged"


  end

end

现在,我正在逐步执行此操作-我已将此耙任务和关联的MCV更新分支到我的主服务器。如果我的网站确实处于生产状态,则可能首先运行import rake任务,然后确认一切运行正常,然后清除旧的AS文件。