将carrierwave文件从一个记录复制到另一个记录的正确方法是什么?

时间:2012-03-29 07:42:47

标签: ruby-on-rails carrierwave

我需要将文件从一个载波对象复制到另一个载波对象。它们是不同的表格和不同类型的上传者。

我开始时:

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等)。

6 个答案:

答案 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_pathstore_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