我需要将文件从一个载波对象复制到另一个载波对象。它们是不同的表格和不同类型的上传者。
我开始时:
user.avatar = image.content
(用户和图像是模型实例,头像和内容是载波加载的上载器),有时可以工作。它似乎一直在本地工作,有文件存储,但在使用雾和s3时间歇性。
在mailing list post我找到了这段代码:
user.avatar = image.content.file
有时再次奏效。
到目前为止我的工作解决方案是:
require "open-uri"
begin
user.avatar = open(image.url)
rescue Errno::ENOENT => e
begin
user.avatar = open(image.path)
rescue Errno::ENOENT => e
# Ok, whatever.
end
end
这不仅难看,而且无法通过扩展验证,因为远程文件的打开不能维护扩展名(jpg,png等)。
答案 0 :(得分:13)
也许一种方法是按照the Carrierwave gem documentation设置远程图像网址?
user.remote_avatar_url = image.url
答案 1 :(得分:7)
从这里讨论的解决方案中,我创建了简单的CopyCarrierwaveFile gem来执行此操作
用法是这样的:
original_resource = User.last
new_resource = User.new
CopyCarrierwaveFile::CopyFileService.new(original_resource, new_resource, :avatar).set_file
new_resource.save
nev_resource.avatar.url # https://...image.jpg
答案 2 :(得分:1)
这是一个(虽然是hacky)解决方案,不需要HTTP请求来获取图像:
module UploadCopier
def self.copy(old, new)
new.instance_variable_set('@_mounters', nil)
old.class.uploaders.each do |column, uploader|
new.send("#{column}=", old.send(column))
end
end
end
old_user = User.last
new_user = User.new
UploadCopier.copy(old_user, new_user)
new_user.save
答案 3 :(得分:1)
我需要将引用从一个模型复制到另一个模型,我通过执行以下操作成功地完成了此操作:
my_new_model.update_column('attachment', my_other_model.attributes["attachment"]);
在这种情况下,我并不关心实际制作文件的副本,也不关心现在有2条记录链接到同一文件(我的系统在上传后从不删除或修改文件)。
对于想要使用相同的上传器将文件引用从一个模型复制到另一个模型的人来说,这可能很有用。
答案 4 :(得分:1)
您可以通过复制文件来做到这一点。
store_path
是 Uploader 类中的一个carrierwave 方法。它返回上传文件的文件夹相对路径。
这个克隆文件方法应该在模型记录保存后调用。
如果没有保存记录,如果您在上传器中指定带有模型 ID 的 store_path
,store_dir
可能会返回错误的路径。
def clone_carrierwave_file(column_name)
origin_files = Dir[File.join(Rails.root, 'public', original_record.send(column_name).store_path, '*')]
return if origin_files.blank?
new_file_folder = File.join(Rails.root, 'public', send(column_name).store_path)
FileUtils.mkdir new_file_folder if !Dir.exist? new_file_folder
FileUtils.cp(origin_files, new_file_folder)
end
希望它有效。
答案 5 :(得分:0)
我只想将头像参考从一个对象复制到另一个对象,对我有用的是:
objectB.avatar.retrieve_from_store!(objectA.avatar.identifier)
objectB.save