2012-03-29 11 views
19

Ho bisogno di copiare un file da un oggetto wave carrier ad un altro. Sono tabelle diverse e diversi tipi di uploader.Qual è il modo corretto di copiare un file carrierwave da un record all'altro?

ho iniziato con:

user.avatar = image.content 

(dove l'utente e l'immagine sono gli esempi di modelli, avatar e contenuti sono il carrierwave montato uploader), che ha lavorato a volte. Sembra funzionare tutto il tempo localmente, con una memoria di file, ma intermittente quando si usa nebbia e s3.

In un mailing list post ho trovato questo codice:

user.avatar = image.content.file 

che ancora una volta ha funzionato a volte.

La mia soluzione di lavoro finora è:

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 

che non è solo brutto, ma non riesce a passare la convalida estensione perché l'apertura di un file remoto non mantiene l'estensione (jpg, png, etc. .).

risposta

12

Forse un modo per farlo è impostare un URL immagine remoto come da the Carrierwave gem documentation?

user.remote_avatar_url = image.url 
+0

Immagine image.content.url? Non sono sicuro che funzionerebbe, dato che l'avatar ha un sacco di versioni con processi diversi che hanno bisogno di un file locale per funzionare, e non voglio che entrambi i record puntino allo stesso file, voglio una copia del file. – Pablo

+1

Il modo in cui remote_blah_url funziona è che essenzialmente "scarica" ​​il file da quell'URL e lo rielabora. Vedi http://stackoverflow.com/questions/5007575/how-to-assign-a-remote-file-to-carrierwave per esempio. – Ibrahim

+3

Non funziona se l'immagine non viene servita su HTTP. Otterrai il seguente errore: 'Icona che tenta di scaricare un file che non viene servito su HTTP' – Pioz

5

Da soluzioni discusse qui ho creato semplice CopyCarrierwaveFile gioiello per fare questo uso

è qualcosa di simile:

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 
0

Ecco una soluzione (anche se hacky) per che non richiede una Richiesta HTTP per recuperare l'immagine:

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 
0

Volevo solo copiare un avatar riferimento da un oggetto all'altro, e che cosa ha funzionato per me è stato:

objectB.avatar.retrieve_from_store!(objectA.avatar.identifier) 
objectB.save 
1

avevo bisogno di copiare un riferimento da un modello ad un altro modello e sono stato con successo in grado di farlo nel modo seguente:

In questo scenario, non mi importava effettivamente di fare una copia del file, né mi importava che 2 record fossero ora collegati allo stesso file (il mio sistema non cancella o modifica mai i file dopo il caricamento).

Questo può essere utile per chi vuole basta copiare il riferimento a un file da un modello ad un altro modello utilizzando lo stesso uploader.

+0

Non ha funzionato per me. https://stackoverflow.com/questions/45901396/carrierwave-sharing-an-image-between-two-models – Dercni

+1

@Dercni fa una buona nota: questo metodo funziona solo se nessun altro campo eccetto il campo 'attachment' è usato per determinare dove si trova il file. – PressingOnAlways

+0

Bene, dopo ore di difficoltà con l'URL remoto ho deciso di utilizzare la soluzione e avere un percorso comune per entrambi i modelli e semplicemente condividere il file, come hai mostrato. – Dercni

Problemi correlati