používáme Ruby on Rails učit vývoj webových aplikací na EPFL Rozšíření Školy. Je to skvělý rámec, který je solidní,vyzkoušený a důvěryhodný a představuje snadno sledovatelnou strukturu při prvních krocích při učení o vývoji webových aplikací.
ale je to také neustále se vyvíjející kus softwaru, s vylepšeními a novými funkcemi, které jsou vydávány každý rok. Jedním z posledních přírůstků do Rails ve verzi 5.2 je funkce ActiveStorage, která poprvé přidává snadnou správu nahrávání souborů do rámce core Rails.
V první iteraci naší webové aplikace rozvojový program, jsme se předmět naučit, jak přidat nahrávání souborů v Rails aplikace. V programu však používáme Rails 5.1 a předmět nahrávání souborů používá jedno z široce používaných řešení třetích stran pro přidávání nahraných souborů, nazvané CarrierWave. Jedná se o solidní klenot třetí strany, který nám umožňuje implementovat nahrávání souborů v aplikaci Rails a používá se v mnoha aplikacích Ruby on Rails v reálném světě-včetně naší platformy pro studenty!
ale se zavedením ActiveStorage se tyto drahokamy třetích stran stávají méně atraktivními než toto nové řešení dodávané uvnitř kolejnic. Ve skutečnosti, Paperclip, jeden z dalších populárních drahokamů nahrávání souborů třetích stran, již oznámil, že je zastaralý ve prospěch ActiveStorage. Vývojáři Paperclip uznali, že ActiveStorage je pro vývojáře lepší volbou a zastavili další práci na vlastním drahokamu.
podívejme se tedy konkrétně na to, co je zapotřebí k přesunu z CarrierWave v kolejnicích 5.1 na ActiveStorage v kolejnicích 5.2.
aplikace
v programu pro vývoj webových aplikací pracujeme na vytvoření webové aplikace s názvem My Bucket List. Jedná se o aplikaci, která umožňuje uživatelům vytvářet a sledovat zážitky, které vždy chtěli dosáhnout. Uživatelé mohou vidět, co ostatní lidé vytvořili, a sledovat je také. Jedna z funkcí v aplikaci umožňuje uživateli nahrát svůj vlastní avatar, a stavíme tuto funkci, abychom se dozvěděli o nahrávání souborů a přílohách pomocí CarrierWave.
Takže nejprve, pojďme se rychlý přehled o tom, co je zapojen s přidáním jednoduché připevnění pomocí CarrierWave.
CarrierWave konfigurace
aby zahrnovala CarrierWave v projektu, musíme:
- Přidat CarrierWave gem
Gemfile
. - zahrňte adaptér CarrierWave pro ActiveRecord do konfiguračního inicializátoru
config/initializers/carrierwave.rb
.
a pak přidat přílohu obrazu k modelu, musíme:
- Generovat Umístil pomocí
rails generate uploader UploaderName
. - přidejte do modelu atribut pro uložení připojeného názvu souboru pro každý záznam s přidruženou migrací databáze.
- upravte hodnoty v uploaderu, například umístění úložiště a výchozí obrázek.
- použijte makro
mount_uploader
v modelu k zahrnutí konkrétního uploaderu. - přidejte pole formuláře souboru, do kterého lze nahrát obrázek.
- přidejte atribut model do seznamu silných parametrů v řadiči, který zpracovává formulář obsahující pole souboru.
Zvažme jeden z těchto bodů dále: v CarrierWave je nutné přidat konkrétní atributy každému modelu, který potřebuje mít připojený soubor. Například model User
, který potřebuje k němu připojený obrázek avatar
, bude potřebovat atribut nazvaný :avatar
, což je String
. To vyžaduje migraci databáze, aby se přidal základní sloupec databáze, plus vytvoření a připojení třídy Uploader
k tomuto atributu v modelu.
to není nijak zvlášť pracné, ale jak uvidíme, ActiveStorage vyžaduje mnohem méně kódu případ od případu.
Jeden bod zdůraznit je, že v mém app — Můj Seznam app — CarrierWave avatar uploader je nastaven s default jednoduché ukládání souborů. V pořadí slova, nahrané obrázky jsou uloženy někde uvnitř public/
složky v aplikaci. Tato přesná cesta je definována ve třídě Uploader
pro avatar a je nastavena na "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
. Toto je cesta vzhledem ke složce public/
, takže nahrané obrázky jsou přímo přístupné přes webový server. To umožňuje přímý přístup k souborům příloh, které můžeme později kontrastovat s ActiveStorage.
upgrade kolejnic
než se podíváte na ActiveStorage, je nutné upgradovat na kolejnice 5.2. To je úkol, který může být docela zapojen, v závislosti na složitosti vaší aplikace. Aplikace, kterou zde používám, kterou stavíme v našem programu WAD, není nijak zvlášť obtížné aktualizovat, ale stále potřebuje určitou péči a pozornost.
zde je to, co jsem udělal pro aktualizaci aplikace My Bucket List z Rails 5.1 na Rails 5.2.
Nejprve jsem vytvořil novou větev v mém repozitáři git, abych izoloval upgrade — je důležité, abyste se mohli vrátit k předchozí pracovní verzi aplikace, pokud se v procesu upgradu něco pokazí!
Na novou pobočku, změnil jsem verzi Kolejnic v Gemfile
z '~> 5.1.2'
'~> 5.2.0'
, a pak běžel bin/bundle update rails
— tento příkaz stáhne novou verzi rails
a všechny související drahokamy v aplikaci. Pro mou aplikaci nebyly žádné konflikty drahokamů, ale pokud používáte drahokamy třetích stran, možná budete muset v tomto okamžiku vyřešit konflikty mezi různými verzemi drahokamů!
po instalaci nového rails gem a jeho závislostí je nutné aktualizovat samotnou aplikaci. Udělal jsem to pomocí bin/bundle exec rails app:update
. Tento příkaz programově aktualizuje všechny potřebné soubory v aplikaci pro práci s Rails 5.2.
ale … tento příkaz přepíše změny, které jste provedli v aplikaci, například config/routes.rb
. Naštěstí se příkaz zeptá, zda přepsat každý soubor, a je možné diff
některý z těchto souborů během tohoto procesu zkontrolovat, co by bylo přepsáno. Výzva pro každé přepsání je , což znamená:
-
Y
pro „Ano, přepište můj soubor“ a je výchozí volbou, pokud stiskneteEnter
. -
n
„ne, ne přepsat můj soubor“ -
a
„Ano, přepsat tento soubor a přepsat každý jiné formáty souborů taky!“. (Mým obecným pravidlem je nikdy nepoužívata
). -
q
„Ukončete tento proces“ -
d
pro „mi Ukázat rozdíly mezi mé soubor a přepsat“ -
h
pro „Ukažte mi seznam, coYnaqdh
znamená“
V mé aplikaci jsem přijal každý přepsat Y
s výjimkou config/routes.rb
a config/locales/en.yml
. Tyto dva soubory byly soubory, které jsem změnil, a tak jsem chtěl zachovat svou verzi, takže jsem si vybral n
.
tento proces upgradu může být více zapojen, pokud máte složitější aplikaci, zejména pokud máte spoustu vlastní konfigurace v některém z konfiguračních souborů prostředí, tj. config/environments/production.rb
, config/environments/test.rb
a config/environments/development.rb
. Aktualizace přidává do těchto souborů důležitá nastavení, ale budete také chtít zachovat vlastní konfiguraci — to je místo, kde pomáhá mít původní verzi aplikace v samostatné větvi git. Poté je možné kód v této staré větvi zkontrolovat, zda je po upgradu stále na svém místě veškerý kód a konfigurace aplikace.
po spuštění bin/bundle exec rails app:update
bylo nutné, abych přidal bootsnap
drahokam do Gemfile
. Jedná se o nový klenot používaný v Rails 5.2, ale není přidán jako součást příkazu app:upgrade
. Tak jsem jen přidal gem 'bootsnap'
do Gemfile
a pak běžel bin/bundle install
.
poté se moje aplikace Bucket List spustila jako před použitím rails server
.
Výměna CarrierWave s ActiveStorage
Takže aplikace nyní běží na Kolejích 5.2, jsem mohl začít nahrazovat CarrierWave s ActiveStorage.
s ActiveStorage není nutné přidávat atributy specifické pro model pro uložení názvů souborů příloh, které jsou nezbytné u CarrierWave. ActiveStorage pracuje se stejnými dvěma přidruženými tabulkami pro všechny přílohy.
aby bylo možné nastavit tyto dvě tabulky, běžel jsem bin/bundle exec rails active_storage:install
následovaný rails db:migrate
. Dvě tabulky jsou active_storage_blobs
a active_storage_attachments
; první je pro podrobnosti připojeného souboru a druhá pro tabulku polymorfních spojení, která spojuje připojený soubor s záznamem modelu.
a tady je důležitý bod: jakmile jsme vytvořili tyto dvě tabulky, nemusíme vytvářet žádné další migrace, abychom zahrnuli přílohy do našich modelů! Díky tomu je ActiveStorage snadno pracovat s z hlediska databáze.
dále jsem se podíval na nahrazení implementace přílohy :avatar
ActiveStorage namísto CarrierWave. V mé aplikaci má každý User
:avatar
. Protože jsem byl s použitím CarrierWave dříve, měl jsem :avatar
atribut namontován na CarrierWave Uploader
v User
model, prohlásil, jako je tento:
class User < ApplicationRecord
# ... various codez mount_uploader :avatar, AvatarUploader # ... other codez
end
V CarrierWave :avatar
příloha může být nahrazen ActiveSupport připevnění pomocí has_one_attached :avatar
, jako je tento:
class User < ApplicationRecord
# ... various codez # commented old uploader for reference
# mount_uploader :avatar, AvatarUploader
has_one_attached :avatar # ... other codez
end
To je změna jednoho řádku kódu. Co jiného je třeba udělat? Jak je například nastaveno umístění úložiště pro nahrávání? Nezapomeňte, že v mé aplikaci je nástroj carrierwave avatar uploader nastaven s výchozím jednoduchým ukládáním souborů a umístění je explicitně nastaveno v souboru avatar_uploader.rb
. Jednoduché ukládání souborů je také výchozí v ActiveStorage. Umístění je nastaveno v souboru config/storage.yml
s výchozí hodnotou pro místní nahrávání.
výchozí config pro ActiveStorage znamená, že nemusím psát kód pro nahrání do práce pro modifikované :avatar
atribut v mé aplikaci. Změnil jsem mechanismus nahrávání úplně z CarrierWave na ActiveStorage a nemusím dělat nic víc: Nepotřebuji provádět žádné změny v řadiči, který spravuje nahrávání, protože :avatar
je již deklarován jako silný parametr. A nemusím měnit pole formuláře souboru v zobrazení, které umožňuje uživatelům vybrat obrázek, který chcete nahrát, protože to je podpořeno atributem “ :avatar
„.
Ale je tu ještě jedna změna, že jsem třeba, aby se k migraci z CarrierWave na ActiveStorage, a to je, jak používat přiložený obrázek v zobrazení. S CarierWave jsem použil metodu avatar_url
k vykreslení úplné cesty k obrázku. S ActiveStorage není Adresa URL souboru vykreslena ze samotného atributu přílohy, ale vykreslena předáním atributu pomocným metodám. Takže úplná adresa URL přílohy může být vykreslena pomocí url_for(user.avatar)
nebo přímo pomocí image_tag
.
je také nutné explicitně kontrolovat, zda příloha je přítomen, takže kompletní použití v názoru by to vypadat nějak takhle:
<% if current_user.avatar.attached? %>
<%= image_tag current_user.avatar, class: 'avatar' %>
<% else %>
<%= image_tag 'default-avatar', class: 'avatar' %>
<% end %>
Jednou jsem aktualizoval odkazy na user.avatar_url
v moje názory s úryvky jako to výše uvedené, měl jsem kompletně přesunuta z CarrierWave na ActiveStorage pro všechny nové obrázky.
starý kód CarrierWave je třeba uklidit a je otázka, co dělat s existujícími nahrávkami, které byly provedeny s CarrierWave. Ale viz níže o tom…
složitější scénáře
téměř všechny scénáře výroby budou složitější než ty, které jsem nastínil výše. Bude nutné zvážit věci, jako jsou obrázky uložené na CDN nebo vzdálených serverech, jako je AWS S3, a změna velikosti obrázků pro miniatury atd. ActiveStorage nám umožňuje dělat spoustu těchto věcí po vybalení z krabice a zdá se, že je velmi dobře navržen pro potřeby vývojářů. Jak můžete očekávat, v průvodci kolejnicemi je dobrá dokumentace.
S ohledem na migraci existující obrázky z CarrierWave na ActiveStorage, to by jistě bylo možné s relativně malým hrábě scénář. Budu se snažit pokrýt, že v budoucím příspěvku.
byl to jednoduchý scénář, ale celkově jsem byl opravdu potěšen tím, jak snadné bylo využít ActiveStorage a nahradit CarrierWave. Také se mi líbí myšlenka, která se dostala do různých částí ActiveStorage, protože se zdá, že vše je v souborech a složkách, které pěkně odpovídají struktuře zbytku Rails. Rozhodně si myslím, že stojí za to dostat se do Rails 5.2, abyste mohli používat ActiveStorage pro nahrávání souborů ve vašich aplikacích!
další informace!
máte zájem dozvědět se více o Ruby a Ruby on Rails? Učím Vývoj Webových Aplikací na EPFL Rozšíření Školy, certifikovaný on-line vzdělávací platforma výuky digitální dovednosti v data science, vývoj webových aplikací, a další. EPFL je jedním z předních světových univerzit a je zařazen „Číslo 1 Young University“ podle Times Higher Education Ranking.