2013-04-04 18 views
7

Próbuję przenieść pliki wokół mojego zasobnika S3 przy użyciu CarrierWave, aby zreorganizować strukturę folderów.Jak mogę reorganizować istniejącą hierarchię folderów za pomocą funkcji CarrierWave?

Przyszedłem do istniejącej aplikacji Rails, w której wszystkie obrazy dla klasy są przesyłane do folderu o nazwie /uploads. Powoduje to problemy, gdy dwaj użytkownicy przesyłają różne obrazy o tej samej nazwie pliku, a drugi obraz zastępuje pierwszy. Aby rozwiązać ten problem, chcę uporządkować foldery, aby umieścić każdy obraz w jego własnym katalogu zgodnie z instancją obiektu ActiveRecord. Używamy CarrierWave do zarządzania przesyłaniem plików.

Stary kod uploader miał następującą metodę:

def store_dir 
    "uploads" 
end 

I zmodyfikowany sposób, aby odzwierciedlić swój nowy system przechowywania plików:

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

Działa to wielkie dla nowych obrazów, ale łamie URL dla starych zdjęć. Istniejące obrazy zgłaszają, że ich URL znajduje się w nowym folderze natychmiast po zmianie modelu, podczas gdy pliki obrazów są nadal przechowywane w /uploads.

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

To nie jest poprawne. Ten obiekt powinien zgłosić swoje logo w /uploads.

Moim rozwiązaniem jest napisanie skryptu do przenoszenia plików obrazów, ale nie znalazłem odpowiednich metod w CarrierWave, aby przenieść pliki. Mój skrypt wyglądałby tak:

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 

Co powinienem zrobić w trzecim wierszu mojego skryptu, aby przenieść plik do nowej lokalizacji?

+1

Czy kiedykolwiek znalazłeś rozwiązanie? Mam ten sam problem. –

+0

To chyba nie dotyczy ciebie, chyba że używasz mgły, ale jest to najlepsze rozwiązanie, które znalazłem i wyglądałem dość ciężko: http: //stackoverflow.com/questions/19038733/need-to- change-the-storage-of-files-in-an-s3-bucket-carrierwave-f –

Odpowiedz

14

OSTRZEŻENIE: Nie zostało to przetestowane, dlatego nie należy go używać przed rozpoczęciem testu.

Oto rzeczy, po zmianie zawartości "store_dir", wszystkie stare pliki zostaną utracone. Już to wiesz. Interakcja z S3 bezpośrednio wydaje się najbardziej oczywistym sposobem rozwiązania tego problemu, ponieważ fala nośna nie ma funkcji ruchu.

Jedną z rzeczy, która może się udać, byłoby ponowne "zapisanie" przesłanych plików i zmiana ścieżki 'store_dir' w wywołaniu zwrotnym 'before: store'.

W swojej przesyłającej:

#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 

A następnie uruchomić skrypt tak:

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

Po tym, upewnij się, że pliki zostały skopiowane do odpowiednich miejsc. Będziesz wtedy musiał usunąć stare pliki do przesłania. Ponadto, wyjąć jednorazowo kod zastosowanie do przesyłania powyżej i zastąpić go nowym ścieżce store_dir:

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

nie mam to przetestowane, więc nie mogę zagwarantować, to będzie działać. Najpierw użyj danych testowych, aby sprawdzić, czy działa i skomentuj tutaj, jeśli odniosłeś jakiś sukces.

+0

Sprawdziło się idealnie dla mnie. Wystarczy przesunąć tysiące plików w mgnieniu oka. Twoje zdrowie. –

+0

Mam problem z replace_script. Ale można zastąpić foldery i pliki na produkcji bez nośnej fali. –

Powiązane problemy