ActiveStorage
ActiveStorage – biblioteka do zarządzania plikami w aplikacjach internetowych, będąca integralną częścią Ruby on Rails od wersji 5.2. Umożliwia łatwe przechowywanie, przetwarzanie i dostarczanie plików (np. zdjęć, dokumentów, wideo) przy użyciu różnych usług zewnętrznych oraz lokalnych systemów plików.
Historia
Projekt ActiveStorage zrodził się z potrzeby ujednolicenia obsługi załączników w Rails. Wcześniej programiści korzystali z gemów CarrierWave lub Paperclip, które wymagały wiele konfiguracji i kodu powtarzalnego. W 2017 roku (wraz z wydaniem Rails 5.2) wprowadzono ActiveStorage jako domyślne rozwiązanie, które integruje się z architekturą MVC oraz ActiveRecord.
Główne założenia i funkcje
- Jednolita API do obsługi plików niezależnie od miejsca ich przechowywania.
- Wsparcie dla popularnych usług chmurowych: Amazon S3, Google Cloud Storage, Microsoft Azure Blob Storage.
- Możliwość przechowywania plików lokalnie (system plików).
- Automatyczne generowanie wariantów (przycinanie, zmiana rozmiaru, konwersja) przy użyciu ImageMagick lub libvips.
- Bezpieczne udostępnianie plików dzięki tymczasowym, podpisanym URL‑om (signed URLs).
- Obsługa wielu załączników (has_many_attached) oraz pojedynczych (has_one_attached).
Architektura
ActiveStorage składa się z trzech głównych komponentów:
- Blob – reprezentacja metadanych pliku (nazwa, rozmiar, typ MIME, klucz w magazynie). Implementowana jako model ActiveRecord.
- Attachment – powiązanie pomiędzy rekordem aplikacyjnym a Blob. Przechowuje informacje o relacji (np.
imageable_type,imageable_id). - Service – warstwa abstrakcji komunikująca się z konkretnym magazynem (np.
:local,:amazon,:google). Definicje usług znajdują się w plikuconfig/storage.yml.
Konfiguracja
Podstawowa konfiguracja znajduje się w pliku config/storage.yml. Przykładowy wpis dla przechowywania lokalnego:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
oraz dla Amazon S3:
amazon:
service: S3
access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %>
secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %>
region: us-east-1
bucket: my-app-bucket
W środowisku production zazwyczaj wybiera się usługę chmurową, a w development i test – lokalną.
Użycie w modelach
Aby dodać możliwości przechowywania plików, w modelu dodaje się jedną z deklaracji:
class User < ApplicationRecord
has_one_attached :avatar # pojedynczy plik
has_many_attached :photos # wiele plików
end
W kontrolerze można zapisywać pliki w następujący sposób:
def create
@user = User.new(user_params)
@user.avatar.attach(params[:user][:avatar])
if @user.save
redirect_to @user, notice: "Użytkownik został utworzony."
else
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email)
end
Warianty i przetwarzanie
ActiveStorage umożliwia definiowanie wariantów obrazu na żądanie:
class Photo < ApplicationRecord
has_one_attached :image
def thumbnail
image.variant(resize_to_limit: [100, 100]).processed
end
end
W widoku:
<%= image_tag @photo.thumbnail %>
Bezpieczeństwo
- Pliki są domyślnie chronione przed nieautoryzowanym dostępem – dostęp uzyskuje się poprzez signed URLs generowane na określony czas.
- Warto konfigurować CSP oraz nagłówki
X-Content-Type-Optionsaby zapobiec atakom typu MIME‑sniffing. - Weryfikację zawartości można rozszerzyć o validacje (np. ograniczenie typu MIME, rozmiaru).
Zalety i wady
| Zalety | Wady |
|---|---|
| Jednolita i intuicyjna API. | Wymaga Rails 5.2+ (starszy projekt może nie być kompatybilny). |
| Głębokie połączenie z ActiveRecord i ActionCable (np. transmisje w czasie rzeczywistym). | Ograniczona kontrola nad niskopoziomowymi operacjami w niektórych usługach (np. pełna obsługa multipart upload w S3). |
| Wsparcie dla wielu usług jednocześnie (przechowywanie w kilku lokalizacjach). | Warianty generowane przy pierwszym żądaniu mogą powodować opóźnienia. |
Automatyczne czyszczenie nieużywanych plików przy użyciu active_storage:purge_unattached. |
Mniej rozbudowane funkcje analizy metadanych w porównaniu z dedykowanymi gemami. |
Powiązane pojęcia
Zobacz także
Więcej informacji na temat zarządzania plikami w środowisku webowym można znaleźć w artykułach: CarrierWave, Paperclip, Shrine.