Grunnleggende Rutekonvensjoner
La oss ta en titt på våre ruter som de er nå, ved hjelp av rake routes
:
$ rake routes Prefix Verb URI Pattern Controller#Action list_posts GET /list_posts(.:format) application#list_posts GET /show_post/:id(.:format) application#show_post new_post GET /new_post(.:format) application#new_post create_post POST /create_post(.:format) application#create_post GET /edit_post/:id(.:format) application#edit_post POST /update_post/:id(.:format) application#update_post POST /delete_post/:id(.:format) application#delete_post POST /create_comment_for_post/:post_id(.:format) application#create_comment POST /list_posts/:post_id/delete_comment/:comment_id(.:format) application#delete_comment list_comments GET /list_comments(.:format) application#list_comments
en av de viktigste innsiktene For Rails-konvensjoner er at datasentriske apper (eller CRUDy apps) har en tendens til å ha svært like måter å la brukere samhandle med applikasjonen, som er:
- en side for å vise en liste over noe
- vis noe
- vis et skjema for å opprette en ny forekomst av noe
- opprett faktisk noe
- oppdater faktisk noe
- slett noe
de syv «interaksjonsmønstrene» er så vanlige at rails gir et sterkt sett med konvensjoner fra ruting til kontrollere, visninger og skjemaer for å gjøre arbeidsflyten enklere. Vi kommer til å fokusere på ruting delen nå.
for ruting er konvensjonen at i stedet for at Vi må komme OPP MED URL-mønstrene, Anbefaler Rails at vi strukturerer Nettadressene og tilhørende kontrollerhandlinger på følgende måte:
Arbeidsflyt | HTTP-VERB | BANE | Kontrollerhandling |
---|---|---|---|
Vis en liste over innlegg | GET | /innlegg | innlegg#index |
Vis et innlegg | GET | /innlegg/:id | innlegg # vis |
Vis siden for å opprette innlegg | FÅ | /innlegg / nytt | innlegg#nytt |
Opprett et innlegg | INNLEGG | /innlegg | innlegg#create |
Vis siden for å redigere et innlegg | GET | /posts/: id / edit | innlegg#edit |
Oppdater et innlegg | PUT / PATCH | /innlegg/: id | innlegg#oppdatering |
Slett et innlegg | SLETT | /innlegg/:id | innlegg # ødelegge |
Vi kan endre post
delen av vår nåværende ruting for å følge denne konvensjonen:
# posts GET /list_posts -> GET /posts posts#index GET /show_post/:id -> GET /posts/:id posts#show GET /new_post -> GET /posts/new posts#new POST /create_post -> POST /posts posts#create GET /edit_post/:id -> GET /posts/:id/edit posts#edit POST /update_post/:id -> PUT/PATCH /posts/:id posts#update POST /delete_post/:id -> DELETE /posts/:id posts#destroy
Og i routes.rb
– filen,
Rails.application.routes.draw do ### posts ### get '/posts' => 'posts#index' get '/posts/new' => 'posts#new' get '/posts/:id' => 'posts#show' post '/posts' => 'posts#create' get '/posts/:id/edit' => 'posts#edit' patch '/posts/:id' => 'posts#update' put '/posts/:id' => 'posts#update' delete '/posts/:id' => 'posts#destroy' # comments later.. ... end
Legg Merke til at med dette nye mønsteret er det mye mindre verb i SELVE NETTADRESSEN, men vi stoler PÅ HTTP-verbene (GET
/POST
/PUT
/PATCH
/DELETE
) å levere semantikken for ellers samme URL-mønstre, for eksempel /posts/:id
.
Merk at PUT
hadde blitt brukt til å oppdatere ressurser inntil nylig, da PATCH
var fast bestemt på å være en bedre semantisk match for denne handlingen. Siden Da Har Rails flyttet til å foretrekke PATCH
, men tillater begge verbene for oppdateringer.
En annen endring vi ser senere er at vi vil rute Alle Nettadresser relatert til innlegg til en PostsController
i stedet for å håndtere alt i ApplicationController
. PostController
‘s handlingsnavn
- ny
- indeks
- vis
- opprett
- rediger
- oppdater
- destroy
er også konvensjoner som svarer til 7-interaksjonen mønstre .
Dette er det sterkeste settet av konvensjoner Som Rails pålegger deg som applikasjonsutvikler. Vi ber deg om å gjøre en innsats for å huske det. Vi vil gå tilbake til dette mange ganger gjennom hele boken for å hjelpe deg med å gjøre det også.
Ruting For Flere Ressurser
ofte må vi ha flere ressurser til stede i NETTADRESSEN. For eksempel for vår bloggapp når vi trenger å ha en rute for å lage en kommentar, er det veldig viktig at vi vet hvilket innlegg denne kommentaren er opprettet på.
Vi gjør dette for øyeblikket:
post 'create_comment_for_post/:post_id' => 'application#create_comment'
Rails-konvensjonen for EN URL med flere tilknyttede ressurser er å starte med» inneholdende «ressursen helt til den» innerste » ressursen. For eksempel vil våre ruter for kommentarer endres til:
post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' get '/comments' => 'comments#index'
semantikken til Disse Nettadressene representerer: «Opprett en kommentar under et bestemt innlegg» og «slett en kommentar under et bestemt innlegg». Den siste ruten, «vis alle kommentarer i systemet», trenger ikke å være «scoped» under et innlegg, så NETTADRESSEN trenger ikke å lede med»/innlegg».
hvis VI trenger å ha flere ressurser I NETTADRESSEN Med Deres Id, er konvensjonen slik at den siste ressursen vil bruke plassholderen :id
og resten vil være :resource_id
som :post_id
.
Restful
REST står for «Representational State Transfer». Det er en programvarearkitektur stil og retningslinje for å skape skalerbare webtjenester. REST, som en måte å strukturere webapplikasjoner på, har mange fasetter til det, men la oss bare se på hvordan det gjelder grensesnittet som vi bruker til å samhandle med webapplikasjoner, Nettadressene.
for å se HVORDAN REST forenkler semantikken Til Nettadresser, la oss gå gjennom et eksempel. La oss si at vi bygger en online pizza bestillingstjeneste. En naï implementering av grensesnittene til tjenesten (Nettadresser) ville være:
/check_order?order_id=2 /place_new_order /pizza_details?type=1 /pay_for_my_order?order_id=12 /cancel_order?order_id=3 /expedite_order?order_id=13
En Avslappende grensesnitt design ville se slik ut:
GET /orders/2 POST /orders GET /pizzas/1 POST /orders/12/payments DELETE /orders/3 POST /orders/13/expeditions
Du kan se, RESTful grensesnitt senter rundt «substantiver» eller «ressurser», fjerne» verb » fra grensesnittene, men i stedet stole på de standardiserte HTTP-verbene (GET
/POST
/PUT
/DELETE
) å levere CRUD semantikk for handlingene. Verbs som check
, place
, cancel
tilordnes DIREKTE TIL HTTP-verb av GET
for å hente, POST
for å opprette og DELETE
for å ødelegge ressurs order
. pay
og expedite
er strukturert som opprettelse (HTTP POST) av underressurser på payments
og expeditions
under ressurs orders
.
RESTful interfaces standardiserte webapplikasjonsinteraksjonsmønstre for å gjøre dem lettere å forstå og programmere mot. Fordi grensesnittene er sentrert rundt å manipulere ressurser, er svarene mye mer forutsigbare. En analogi av Hvordan RESTful arkitektur mønster forenkler samhandling med webtjenester ville være hvordan Relasjonsdatabasen og SQL språk forenkler datalagring. Før Relasjonsdatabase og SQL ble data vanligvis lagret i proprietære systemer med spesifikk logikk for å samhandle med dem. Relasjonsdatabaser og SQL ga en felles datastruktur (dataposter som rader og kolonner lagret i tabeller) og et sett med felles grensesnitt – fire enkle verb av SELECT
, INSERT
, UPDATE
og DELETE
som kan støtte alle typer applikasjoner.
Vedta En RESTful grensesnitt for web app vil også effektivisere programmet til å justere med hvordan backend data lagres i databaser, og gjør utviklingen enklere. Vi ser det i de følgende kapitlene.
Ressursnotasjon
Vi har snakket om Rails ‘ ruting konvensjoner, Og RESTful URL mønstre. Nå vil vår routes.rb
fil se ut som følgende:
### config/routes.rb ### Rails.application.routes.draw do ### posts ### get '/posts' => 'posts#index' get '/posts/new' => 'posts#new' get '/posts/:id' => 'posts#show' post '/posts' => 'posts#create' get '/posts/:id/edit' => 'posts#edit' patch '/posts/:id' => 'posts#update' put '/posts/:id' => 'posts#update' delete '/posts/:id' => 'posts#destroy' ### comments ### get '/comments' => 'comments#index' post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' end
faktisk er rutene som det vi har i delen posts
svært vanlige, så Rails gir en spesiell resources
notasjon som bidrar til å generere dem for deg.
Vi kan ganske enkelt gjøre:
resources :posts
denne linjen vil automatisk generere de 8 linjene vi hadde før. Merk at For handlingen update
Tillater Rails både PUT
og PATCH
verb, av kompatibilitetshensyn.
du kan kjøre bundle exec rake routes
i kommandolinjemiljøet for å bekrefte at det genererer nøyaktig samme sett med ruter.
Merk at denne enkeltlinjen vil generere 8 ruter. I vårt tilfelle trenger vi alle ruter her, men hvis du bare trenger en delmengde av rutene, kan du definere dem mer eksplisitt som:
resources :posts, only:
denne linjen ovenfor vil bare generere 3 ruter for deg – type bundle exec rake routes
for å sjekke det ut.
Nestede Ressurser
Rails lar oss også neste ressurser for å lage URL-mønstre med flere ressurser, se nedenfor:
### config/routes.rb ### Rails.application.routes.draw do resources :posts do resources :comments, only: end resources :comments, only: :index end
Kjør bundle exec rake routes
og se utgangen – det skal være det samme som det vi hadde før.
Banehjelpere
når du kjører bundle exec rake routes
, legg merke til Prefix
– kolonnen for noen av disse rutene. Disse er her for å hjelpe oss å vite hvordan Du bruker Rails ‘ gitt banen hjelpere for våre ruter. Vi kan bruke disse prefiksene etterfulgt av _path
i våre kontroller og visninger for enkelt å bygge baner.
for eksempel:
posts_path # => '/posts' post_id = 123 post_comments_path(post_id) # => '/posts/123/comments'
Hva er fordelen med Å bruke URL-hjelpere, i stedet for hard koding av banene som /posts/123/comments
direkte i koden din? (for eksempel i kontrolleren din handling?) Grunnen til at du vil bruke banehjelpere er at hvis du vil endre URL-mønstrene i appen din, er DET mye enklere å bruke URL-hjelperne til å returnere en annen vei – la oss se på et eksempel:
get '/register', to: 'users#new', as: 'register'
når vi legger til «as» – klausulen på denne ruten, hvis du kjører bundle exec rake routes
, ser du kolonnen Prefix
med register
, og du kan bruke register_path
for å få /register
banen. Nå, hvis vi vil endre banen til /login
, er alt vi trenger å gjøre bare å:
get '/login', to: 'users#new', as: 'register'
nå gir vår register_path
oss /login
. Vi trenger ikke å endre koden vår i Rails-appen i det hele tatt.
Flere Rutekonvensjoner
før Vi går Videre, la oss ta en rask titt på et par variasjoner av det vi allerede har sett, samt noen andre funksjoner som er tilgjengelige for Oss I Rails routing:
### config/routes.rb ### Rails.application.routes.draw do # pointing our homepage (root path) to posts#index root to: 'posts#index' # `match` & `via:` allow us to define one route and use several HTTP verbs # `as:` lets us define the name of the route prefix match '/authors/:id' => 'authors#update', via: , as: :update_author # update_author PUT|PATCH /authors/:id(.:format) authors#update resources :posts do # define extra params to pass for requests to a route get 'popular', on: :collection, action: :index, popular: true # popular_posts GET /posts/popular(.:format) posts#index {:popular=>true} get 'preview', on: :member # ... end # we can even use routes to redirect get '/home', to: redirect('/') end
La oss bryte ned alle funksjonene som er nevnt ovenfor en om gangen.
-
root:
root
brukes til å angi hvilke handlinger som skal tilordnes «/»(nettadressen på øverste NIVÅ til nettstedet vårt som ikke har noen bane).Roten URL til nettstedet ditt / app er den mest brukte, på grunn av detteroot
bør spesifiseres øverst i routes-filen. -
match + via:
match
brukes til å matche URL-mønstre til en eller flere ruter. Vi kan også spesifisere HVILKET HTTP-verb SOM kan brukes til å matche EN URL med dette mønsteret. Vi gjør dette ved å sende inn en hash tilmatch
– metoden. Nøkkelen for denne hash ervia
, og verdien er EN rekke HTTP-verb.match
er en mer generell form for NOEN MER vanlige HTTP-rutingsmetoder, for eksempelget
,post
ogdelete
. Det kan ta alle de samme alternativene som disse metodene, men i forhold til disse metodene gir det litt mer fleksibilitet.
ved å brukematch
kan vi for eksempel angi EN URL som samsvarer med to forskjellige ruter, hver tilsvarer to FORSKJELLIGE HTTP-verb. Normalt vil dette kreve to kommandoer, i stedet for en. Vi kan se dette fra vårt eksempel ovenfor, hvor vi matcher URL-mønsteret'/authors/:id'
til handlingen'authors#update'
. Vi angir DERETTER HVILKE HTTP-verb SOM kan brukes til å utstede forespørselen for DEN NETTADRESSEN medvia:
. Angi ALLTID EN HTTP-metode når du brukermatch
, hvis du ikke gjør det, kan det ha negative konsekvenser for programmets sikkerhet.
match
presenterer et annet alternativ for ruting til bestemte handlinger i Rails. Generelt er det best å holde fast ved de mer brukteHttpHelpers
– metodene, for eksempelget
ogpost
. -
as: vi nevnte litt tidligere at alternativet
as:
kan brukes med vår rutedeklarasjon for å endre prefikset for VÅRE URL-hjelpere. Dette kan brukes på ulike måter. Vi kan brukeas:
for å gjøre VÅRE URL hjelpere bedre matche tilpassede Nettadresser. En annen bruk er å endre gjeldende URL path helper til noe mer intuitivt eller noe som samsvarer bedre med ressursene i et program. -
samlingsrute: Se hvordan over vi nest vår
/popular
rute underposts
ressurs. Vi bruker daon: :collection
for å spesifisere hvilken del av en ressurs vi hekker denne ruten under. Vi har mange innlegg, så det regnes som en samling. Ved å spesifisereon: :collection
sier vi, » Match EN URL med sti/posts/popular
.»Hvis vi ikke la tilon: :collection
, Vil Rails anta at denne ruten tilsvarer en annen ressurs knyttet til et enkelt medlem av vår innleggssamling. I så fall vil vår rute bli/posts/:id/popular
. Vi kan også angi flere samlingsruter ved hjelp av et blokkformat.
collection do get 'popular' end
- passerer en ekstra parameter: Vi kan angi en standardparameter som alltid blir sendt inn med vår
params
hash når vi matches med bestemte Nettadresser. Det er to måter å spesifisere dette på; en måte er den samme måten vi gjør over:
get 'popular', on: :collection, action: :index, popular: true
popular: true
vil bli sendt til vår handling som den populære ruten samsvarer med via params
hash. Den vil ha en nøkkel på :popular
og en verdi på true
. Vi kan også bruke mer eksplisitt syntaks ved å sende en hash til vår rutemetode get
, hvor nøkkelen er defaults:
og verdien er en annen hash som inneholder navnet på parameteren vi vil passere til vår handling.
get 'popular', on: :collection, action: :index, defaults: { popular: true}
-
medlemsrute: vi kan bruke
on: member
for å angi at ruten vår samsvarer med et medlem av en samling. Hvis vi bruker dette vil det dynamiske segmentet vises som:id
. EN URL-hjelper vil også bli opprettet sompreview_post
. Ved å spesifisere denne ruten medon: member
, forteller Vi Rails at dette er medlem av denne ressursen. At det ikke bare er en annen ressurs nestet under innlegg, men nærmere knyttet eller relatert til våre innlegg i denne applikasjonen. Flere medlemsruter kan defineres ved hjelp av et blokkformat; dette formatet bruker samme syntaks som blokkformatet for å definere flere samlingsruter, bare erstattcollection
medmember
. -
redirect: Det er et annet konsept å snakke om som vises i vårt eksempel ovenfor, og det er omdirigering. Rails gir oss muligheten til å omdirigere fra en bane til en annen ved hjelp av en redirect helper i forbindelse med en rute.
get '/home', to: redirect('/')
. Hvis noen prøver å få tilgang til banen/home
, blir de umiddelbart omdirigert til rotbanen/
. Dette er ikke begrenset til bare EN URL-bane selvfølgelig; vi kan også ha noe slikt:get '/home', to: redirect('/travel')
.
Gjennomgang
Rails ruter står foran et program. En rute tolker en innkommende HTTP-forespørsel og:
- matcher en forespørsel til en kontrollerhandling basert på kombinasjonen AV ET HTTP-verb og forespørselsadressemønsteret
- fanger opp data i URL-ADRESSEN som skal være tilgjengelig i
params
i kontrollerhandlinger - Rails oppfordrer utviklere til å bruke RESTful URL-mønstre når de konfigurerer ruter, med konseptualisering av manipulering av ressurser med HTTP-verb.
- du kan bruke makroen
resources
til å generere RESTful ruter veldig raskt.