ruby on rails - mount_uploader - ¿Cuál es la forma correcta de copiar un archivo de carrierwave de un registro a otro?
rails image upload (5)
Necesito copiar un archivo de un objeto wave de portadora a otro. Son diferentes tablas y diferentes tipos de cargadores.
Comencé con:
user.avatar = image.content
(donde el usuario y la imagen son instancias de modelo, avatar y contenido son los cargadores montados en carrierwave) que funcionaron a veces. Parece funcionar todo el tiempo localmente, con un almacenamiento de archivos, pero intermitente cuando se usa fog y s3.
En una publicación de la lista de correo encontré este código:
user.avatar = image.content.file
que otra vez funcionó a veces.
Mi solución de trabajo hasta ahora es:
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
lo que no solo es feo, sino que no pasa la validación de la extensión porque la apertura de un archivo remoto no mantiene la extensión (jpg, png, etc.).
Aquí hay una solución (aunque hacky) que no requiere una solicitud HTTP para obtener la imagen:
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
De las soluciones discutidas aquí, CopyCarrierwaveFile gema CopyCarrierwaveFile simple para hacer esto
El uso es algo como esto:
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
Necesitaba copiar una referencia de un modelo a otro y logré hacerlo haciendo lo siguiente:
my_new_model.update_column(''attachment'', my_other_model.attributes["attachment"]);
En este escenario, no me importó realmente hacer una copia del archivo, ni me importó que 2 registros ahora estuvieran vinculados al mismo archivo (mi sistema nunca elimina ni modifica los archivos después de cargarlos).
Esto puede ser útil para cualquier persona que quiera simplemente copiar la referencia a un archivo de un modelo a otro usando el mismo cargador.
Solo quería copiar una referencia de avatar de un objeto a otro, y lo que funcionó para mí fue:
objectB.avatar.retrieve_from_store!(objectA.avatar.identifier)
objectB.save
Tal vez una forma de hacerlo sea establecer una URL de imagen remota según la documentación de Carrierwave gem ?
user.remote_avatar_url = image.url