W naszej mini-aplikacji brakuje jeszcze funkcjonalności usuwania plików. Tym razem stworzymy dwa serwisy:
- usuwający plik z serwera,
- wywołujący serwis nr.1 i po pomyślnym jego wykonaniu, usuwający rekord z bazy danych.
Chcemy mieć pewność, że usuniemy dane z bazy danych dopiero wtedy, kiedy pliku już nie będzie na serwerze. Nie chcielibyśmy dopuścić do sytuacji, kiedy na przykład tracimy połączenie z internetem, plik zostaje, a rekord w bazie danych został usunięty. Co prawda, mamy możliwość synchronizacji w takim przypadku, jednak nie chcemy mnożyć czynności, które użytkownik musi wykonywać w aplikacji.
Rozpocznijmy więc od usuwania pliku. Tak jak przy uploadzie, do usunięcia potrzebujemy jednej, prostej metody: delete
.
require 'net/ftp'
module Media
class DeleteFromFTP < ApplicationService
def call(medium_name)
Net::FTP.open(host) do |ftp|
ftp.login(username, password)
ftp.delete(medium_name)
end
rescue StandardError
'failed'
end
end
end
Mając do dyspozycji taki serwis, usunięcie pliku może wyglądać w ten sposób:
medium = Medium.find_by(name: 'raport_out_of_date.xls')
Media::DeleteFromFTP.new.call(medium.name)
Jeżeli wykonanie powyższych linijek kodu nie zwróciło błędu, plik powininen zostać usunięty z serwera FTP.
Opakujmy zatem powstały serwis w jeszcze jeden, który będzie usuwał rekord z bazy danych. W pierwszej kolejności będzie wywoływał serwis DeleteFromFTP
, a następnie, jeżeli nie pojawią się żadne błędy, usunie powiązany z plikiem rekord.
module Media
class Destroy
def call(medium)
service = DeleteFromFTP.call(medium.name)
return 'Failed' if service == 'failed'
medium.destroy
end
end
end
W tym serwisie nie potrzebujemy modułu net/ftp
, ani danych logowania więc pomijamy require 'net/ftp
oraz ApplicationService
. Dzięki temu, że wykonując Media::Destroy#call
jesteśmy ‘wewnątrz’ modułu Media
, wezwanie serwisu DeleteFromFTP
może zostać wykonane bez opisywania całej ścieżki wiodącej do niego (tzn. możemy ominąć Media::
). Zgodnie z założeniem serwis zwraca komunikat “Failed” jeżeli usunięcie pliku z serwera się nie powiedzie oraz przerywa działanie.
Koniec z FTP
To by było na tyle jeśli chodzi o serię ‘Dealing with FTP’. Kod zamieszczony tutaj jest mocno uproszczony i napisany w nienajlepszym stylu, ale założeniem było przedstawienie podstawowych narzędzi jakie oferuje język Ruby do obsługi plików przez protokół FTP, a nie budowanie pełnoprawnej aplikacji webowej. Dzięki za uwagę :)