Vi bruker Ruby On Rails til å undervise i webapplikasjonsutvikling på EPFL Extension School. Det er et flott rammeverk som er solid, prøvd og klarert og presenterer en lett å følge struktur når du tar dine første skritt å lære om webutvikling.
Men det er også et stadig utviklende stykke programvare, med forbedringer og nye funksjoner blir utgitt hvert år. En av de siste tilskuddene Til Rails i versjon 5.2 Er ActiveStorage-funksjonen, som legger til enkel filopplastingsadministrasjon til core Rails framework for første gang.
i den første iterasjonen av vårt webapplikasjonsutviklingsprogram, inkluderer vi et emne for å lære å legge til filopplasting i Et Rails-program. Vi bruker Rails 5.1 i programmet imidlertid, og filopplastingsfaget bruker en av de mye brukte tredjepartsløsningene for å legge til filopplastinger, Kalt CarrierWave. Dette er en solid tredjeparts perle som gjør at vi kan implementere filopplasting i En Rails-app og er i bruk i Mange Virkelige Ruby on Rails — apper-inkludert vår læringsplattform!
Men med introduksjonen Av ActiveStorage blir disse tredjepartsperlene mindre attraktive enn denne nye løsningen som er samlet inn I Skinner. Faktisk, Paperclip, en av de andre populære tredjeparts filopplasting gems, har allerede annonsert at det er foreldet I Favør Av ActiveStorage. Utviklerne av Paperclip har anerkjent At ActiveStorage er et bedre valg for utviklere og stoppet videre arbeid på egen perle.
så la oss se nærmere på hva som trengs for å flytte Fra CarrierWave I Rails 5.1 Til ActiveStorage i Rails 5.2.
søknaden
i webapplikasjonsutviklingsprogrammet jobber vi gjennom å bygge en webapplikasjon kalt My Bucket List. Dette er en app som lar brukerne opprette og spore opplevelser som de alltid har ønsket å oppnå. Brukere kan se hva andre mennesker har opprettet og spore dem også. En av funksjonene i appen tillater en bruker å laste opp sin egen avatar, og vi bygger den funksjonen for å lære om filopplasting og vedlegg ved Hjelp Av CarrierWave.
så først, la oss få en rask gjennomgang av hva som er involvert med å legge til et enkelt vedlegg ved Hjelp Av CarrierWave.
CarrierWave configuration
for å inkludere CarrierWave i et prosjekt, må vi:
- Legg CarrierWave perle til
Gemfile
. - Inkluder CarrierWave adapter For ActiveRecord i en config initializer,
config/initializers/carrierwave.rb
.
og deretter for å legge til et bildevedlegg til en modell, må vi:
- Generer En Opplaster ved hjelp av
rails generate uploader UploaderName
. - Legg til et attributt på modellen for å lagre det vedlagte filnavnet for hver post, med tilknyttet databaseoverføring.
- Rediger verdier i opplasteren, for eksempel opplastingssted og standardbilde.
- bruk makroen
mount_uploader
i modellen for å inkludere den bestemte opplasteren. - Legg til et filskjemafelt der et bilde kan lastes opp.
- Legg til modellattributtet i listen over sterke parametere i kontrolleren som håndterer skjemaet som inneholder filfeltet.
la oss vurdere et av disse punktene videre: I CarrierWave er det nødvendig å legge til spesifikke attributter til enhver modell som må ha en vedlagt fil. For eksempel vil en User
– modell som trenger et avatar
– bilde knyttet til det, trenge et attributt kalt :avatar
som er en String
. Dette krever en databaseoverføring for å legge til den underliggende databasekolonnen, i tillegg til å opprette og montere en Uploader
– klasse til dette attributtet i modellen.
Dette er ikke spesielt arbeidskrevende, men Som Vi ser, Krever ActiveStorage mye mindre kode fra sak til sak.
Ett poeng å markere er at I min app — My Bucket List app — CarrierWave avatar uploader er satt opp med standard enkel fillagring. For ord lagres opplastede bilder et sted inne i mappen public/
i søknaden. Den nøyaktige banen er definert i klassen Uploader
for avataren, og er satt til "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
. Dette er en bane i forhold til mappen public/
, slik at opplastede bilder er direkte tilgjengelige via webserveren. Dette gir direkte tilgang til vedleggsfilene, som vi kan kontrastere Med ActiveStorage senere.
Oppgradering Av Rails
før Du ser På ActiveStorage, er det nødvendig å oppgradere Til Rails 5.2. Dette er en oppgave som kan være ganske involvert, avhengig av kompleksiteten i søknaden din. Programmet som jeg bruker her, som vi bygger i VÅRT WAD-program, er ikke spesielt vanskelig å oppdatere, men det trenger fortsatt litt omsorg og oppmerksomhet.
Her er hva jeg gjorde for å oppdatere Min Bøtte liste søknad Fra Rails 5.1 Til Rails 5.2.
Først opprettet jeg en ny gren i git-depotet mitt for å isolere oppgraderingen-det er viktig å kunne gå tilbake til den forrige arbeidsversjonen av en app hvis noe går galt i oppgraderingsprosessen!
på den nye grenen endret jeg Versjonen Av Rails i Gemfile
fra '~> 5.1.2'
til '~> 5.2.0'
, og kjørte deretter bin/bundle update rails
— denne kommandoen laster ned den nye versjonen av rails
og alle de relaterte perlene i søknaden. For min søknad, det var ingen perle konflikter, men hvis du bruker tredjeparts gems, må du kanskje løse konflikter mellom ulike perle versjoner på dette punktet!
etter å ha installert den nye Rails gem og det er avhengigheter, er det nødvendig å oppdatere selve programmet. Jeg gjorde dette ved hjelp av bin/bundle exec rails app:update
. Denne kommandoen oppdaterer programmatisk alle nødvendige filer i programmet for å arbeide Med Rails 5.2.
Men … denne kommandoen overskriver endringer du har gjort i programmet, for eksempel config/routes.rb
. Heldigvis spør kommandoen om å overskrive hver fil, og det er mulig å diff
noen av disse filene under denne prosessen for å sjekke hva som vil bli overskrevet. Meldingen for hver overskriving er , som betyr:
-
Y
for «Ja, overskrive filen min», og er standardalternativet hvis du bare trykkerEnter
. -
n
for «nei, skriv ikke over filen min» -
a
for » Ja, overskrive denne filen og overskrive alle andre filer også!». (Min generelle regel er aldri bruka
). -
q
for «Avslutt denne prosessen» -
d
for «Vis meg forskjellene mellom filen min og overskrivingen» -
h
for «Vis meg en liste over hvaYnaqdh
betyr»
I søknaden min aksepterte jeg hver overskrive med Y
unntatt config/routes.rb
og config/locales/en.yml
. De to filene var filer som jeg hadde endret, og så jeg ønsket å beholde min versjon, så valgte n
.
denne oppgraderingsprosessen kan være mer involvert hvis du har et mer komplekst program, spesielt hvis du har mye tilpasset konfigurasjon i noen av miljøkonfigurasjonsfilene, dvs. config/environments/production.rb
, config/environments/test.rb
og config/environments/development.rb
. Oppgraderingen legger viktige innstillinger til disse filene, men du vil også beholde din egen tilpassede konfigurasjon-det er her å ha den opprinnelige versjonen av programmet i en egen git-gren hjelper. Det er da mulig å koden i denne gamle grenen for å sjekke at all programkode og konfigurasjon fortsatt er på plass etter oppgraderingen.
etter å ha kjørt bin/bundle exec rails app:update
, var det nødvendig for meg å legge til bootsnap
perlen til Gemfile
. Dette er en ny perle brukt i Rails 5.2, men det er ikke lagt til som en del av kommandoen app:upgrade
. Så jeg har nettopp lagt til gem 'bootsnap'
til Gemfile
og kjørte bin/bundle install
.
etter dette startet Min Bucket List-applikasjon som før du brukte rails server
.
Bytte CarrierWave Med ActiveStorage
Så, med programmet som nå kjører På Rails 5.2, kunne jeg begynne å erstatte CarrierWave Med ActiveStorage.
Med ActiveStorage er det unødvendig å legge til modellspesifikke attributter for å lagre vedleggsfilnavnene som er nødvendige med CarrierWave. ActiveStorage fungerer med de samme to tilknyttede tabellene for alle vedlegg.
for å sette opp disse to tabellene løp jeg bin/bundle exec rails active_storage:install
etterfulgt av rails db:migrate
. De to tabellene er active_storage_blobs
og active_storage_attachments
; den første er for detaljene i den vedlagte filen, og den andre er for den polymorfe sammenføyningstabellen som knytter en vedlagt fil til en modellpost.
og her er det viktige punktet: når vi har opprettet disse to tabellene, trenger vi ikke å opprette andre migreringer for å inkludere vedlegg i våre modeller! Dette gjør ActiveStorage lett å jobbe med fra en database perspektiv.
Deretter så Jeg på å erstatte implementeringen av :avatar
vedlegget Med ActiveStorage i stedet For CarrierWave. I min app har hver User
en :avatar
. Fordi Jeg brukte CarrierWave tidligere, hadde jeg en :avatar
attributt montert på En CarrierWave Uploader
i modellen User
, erklært slik:
class User < ApplicationRecord
# ... various codez mount_uploader :avatar, AvatarUploader # ... other codez
end
CarrierWave :avatar
– vedlegget kan erstattes med Et ActiveSupport-vedlegg ved å bruke has_one_attached :avatar
, som dette:
class User < ApplicationRecord
# ... various codez # commented old uploader for reference
# mount_uploader :avatar, AvatarUploader
has_one_attached :avatar # ... other codez
end
det er en endring til en linje med kode. På dette punktet, hva annet må gjøres? For eksempel, hvordan er opplastingsstedet satt? Husk at I min app Er carrierwave avatar uploader satt opp med standard enkel fillagring, og plasseringen for dette er eksplisitt angitt i filen avatar_uploader.rb
. Enkel fillagring er standard i ActiveStorage også. Plasseringen er angitt i filen config/storage.yml
, med en standardverdi for lokale opplastinger.
standardkonfigurasjonen For ActiveStorage betyr at jeg ikke trenger å skrive mer kode for opplastingene mine for å fungere for det modifiserte :avatar
– attributtet i programmet mitt. Jeg har endret opplastingsmekanismen helt Fra CarrierWave Til ActiveStorage, og jeg trenger ikke å gjøre noe mer: Jeg trenger ikke å gjøre noen endringer I Kontrolleren som styrer opplastingen, fordi :avatar
allerede er erklært som en sterk parameter. Og jeg trenger ikke å endre filformularfeltet i visningen som lar brukerne velge et bilde som skal lastes opp, fordi dette støttes av :avatar
«attributt».
Men det er en endring som jeg må gjøre for å migrere Fra CarrierWave Til ActiveStorage, og det er hvordan du bruker det vedlagte bildet i visninger. Med CarierWave brukte jeg avatar_url
– metoden for å gjengi hele bildebanen. Med ActiveStorage blir FILADRESSEN ikke gjengitt fra selve vedleggsattributtet, men gjengitt ved å overføre attributtet til hjelpemetoder. SÅ hele vedleggsadressen kan gjengis ved hjelp av url_for(user.avatar)
, eller direkte med image_tag
.
det er også nødvendig å eksplisitt sjekke om vedlegget er til stede, så en fullstendig bruk i en visning vil se slik ut:
<% if current_user.avatar.attached? %>
<%= image_tag current_user.avatar, class: 'avatar' %>
<% else %>
<%= image_tag 'default-avatar', class: 'avatar' %>
<% end %>
Når jeg oppdaterte referansene til user.avatar_url
i mine synspunkter med utdrag som det ovenfor, hadde jeg flyttet helt Fra CarrierWave Til ActiveStorage for alle nye opplastinger.
den gamle CarrierWave-koden må ryddes opp, og det er et spørsmål om hva du skal gjøre med eksisterende opplastinger som ble gjort med CarrierWave. Men se nedenfor om det…
mer komplekse scenarier
Nesten alle produksjonsscenarier vil være mer komplekse enn det jeg skisserte ovenfor. Det vil være nødvendig å vurdere ting som opplastinger som lagres På Cdn-er eller eksterne servere som AWS S3, og bildestørrelse for miniatyrbilder, etc. ActiveStorage tillater oss å gjøre mange av disse tingene ut av boksen også og virker veldig godt konstruert for utviklernes behov. Som du kanskje forventer, er det god dokumentasjon i Skinneguiden.
med hensyn til å migrere eksisterende opplastinger fra CarrierWave Til ActiveStorage, ville dette sikkert være mulig med et relativt lite rake-skript. Jeg vil ta sikte på å dekke det i et fremtidig innlegg.
Dette var et enkelt scenario, men generelt var jeg veldig fornøyd med hvor lett Det var å gjøre Bruk Av ActiveStorage og erstatte CarrierWave med Det. Jeg liker også tanken som har gått inn i De ulike delene Av ActiveStorage, da alt ser ut til å være i filer og mapper som passer fint til strukturen til Resten av Rails. Jeg tror definitivt det er verdt Å komme Inn I Rails 5.2 for å kunne bruke ActiveStorage for filopplasting i dine applikasjoner!
Lær mer!
interessert i å lære Mer Om Ruby og Ruby on Rails? Jeg lærer Webapplikasjonsutvikling på EPFL Extension School, en sertifisert online læringsplattform som lærer digitale ferdigheter innen datavitenskap, webapplikasjonsutvikling og mer. EPFL ER et av verdens ledende universiteter og er rangert Som «Nummer 1 Young University» av Times Higher Education Ranking.