出于各种原因,我将上传的文件从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问题:
答案 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文件。