2013-04-04 12 views
7

Ich versuche, Dateien um meine S3-Bucket mit CarrierWave zu verschieben, um die Ordnerstruktur zu reorganisieren.Wie kann ich eine bestehende Ordnerhierarchie mit CarrierWave reorganisieren?

Ich kam zu einer vorhandenen Rails-Anwendung, wo alle Bilder für eine Klasse in einen Ordner namens /uploads hochgeladen werden. Dies führt zu Problemen, wenn zwei Benutzer unterschiedliche Bilder mit demselben Dateinamen hochladen, während das zweite Bild das erste Bild überschreibt. Um dies zu beheben, möchte ich die Ordner neu organisieren, um jedes Bild in einem eigenen Verzeichnis gemäß der ActiveRecord Objektinstanz zu platzieren. Wir verwenden CarrierWave, um Datei-Uploads zu verwalten.

Der alte Uploader Code hatte die folgende Methode:

def store_dir 
    "uploads" 
end 

ich die Methode geändert, um mein neues Dateispeicherschema widerspiegeln:

def store_dir 
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
end 

Dies funktioniert gut für neue Bilder, aber bricht die URL für alte Bilder. Vorhandene Bilder melden ihre URL sofort im neuen Ordner, wenn ich das Modell ändere, während die Bilddateien immer noch in /uploads gespeichert sind.

> object.logo.store_dir 
=> "uploads/object/logo/133" 

Dies ist nicht korrekt. Dieses Objekt sollte sein Logo in /uploads melden.

Meine Lösung ist ein Skript schreiben, um die Bilddateien zu verschieben, aber ich habe nicht die richtigen Methoden in CarrierWave gefunden, um die Dateien zu verschieben. Mein Skript würde wie folgt aussehen:

MyClass.all.each |image| 
    filename = file.name #This method exists in my uploader, returns the file name 
    #Move the file from "/uploads" to "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
end 

Was soll ich in Zeile drei meiner Skript tun, um die Datei an eine neue Position zu bewegen?

+1

Sie haben jemals eine Lösung gefunden? Ich habe das gleiche Problem. –

+0

Dies ist vielleicht nicht auf Sie anwendbar, es sei denn, Sie verwenden Nebel, aber das ist die beste Lösung, die ich gefunden habe und ich habe ziemlich hart gesucht: http: //stackoverflow.com/questions/19038733/need-to- change-the-storage-Verzeichnis-von-Dateien-in-s3-bucket-carrierwave-f –

Antwort

14

WARNUNG: Dies ist nicht getestet, also bitte nicht bei der Produktion verwenden, bevor Sie es testen.

Hier ist die Sache, sobald Sie den Inhalt von "store_dir" ändern, werden alle Ihre alten Uploads werden vermisst. Das weißt du schon. Die Interaktion mit S3 scheint die naheliegendste Lösung zu sein, da carrierwave keine Bewegungsfunktion hat.

Eine Sache, die funktionieren könnte, wäre, Ihre Uploads wieder zu 'speichern' und den 'store_dir' Pfad im 'before: store' Callback zu ändern.

In Ihrem Uploader:

#Use the old uploads directory so carriewave knows where the original upload is 
def store_dir 
    'uploads' 
end 

before :store, :swap_out_store_dir 

def swap_out_store_dir 
    self.class_eval do 
    def store_dir 
     "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
    end 
    end 
end 

Und dann ein Skript wie folgt ausführen:

MyClass.all.each do |image| 
    image.image.cache! #create a local cache so that store! has something to store 
    image.image.store! 
end 

Danach, stellen Sie sicher, dass die Dateien an die richtigen Stellen kopiert wurden. Sie müssen dann die alten Upload-Dateien löschen. Entfernen Sie auch die Verwendung Uploader Code einmal oben und ersetzen Sie es mit Ihrem neuen store_dir Pfad:

def store_dir 
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id} " 
end 

Ich habe nicht getestet heraus, so kann ich nicht garantieren, es wird funktionieren. Bitte verwenden Sie zuerst Testdaten, um zu sehen, ob es funktioniert und kommentieren Sie hier, wenn Sie Erfolg hatten.

+0

Arbeitete perfekt für mich. Hat nur tausende Dateien im Handumdrehen verschoben. Prost. –

+0

Ich hatte das Problem mit replace_script. Aber Sie können Ordner und Dateien bei der Produktion ohne Trägerwelle ersetzen. –