grundlæggende Rutekonventioner
lad os se på vores ruter, som de er nu, ved hjælp af 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 af de vigtigste indsigter for Rails-konventioner er, at datacentriske apps (eller CRUDy apps) har tendens til at have meget lignende måder at lade brugerne interagere med applikationen, som er:
- en side for at se en liste over noget
- se noget
- Vis en formular for at oprette en ny forekomst af noget
- Opret faktisk noget
- Vis en formular for at redigere en forekomst af noget
- Opdater faktisk noget
- slet noget
disse syv “interaktionsmønstre” er så almindelige, at Rails giver et stærkt sæt konventioner fra routing til controllere, visninger og formularer for at gøre disse arbejdsgange enklere. Vi vil fokusere på routingdelen nu.
til routing er konventionen, at i stedet for at vi skal komme med URL-mønstrene, anbefaler Rails, at vi strukturerer URL ‘ erne og tilsvarende controller-handlinger på følgende måde:
arbejdsgang | HTTP VERB | sti | Controller handling |
---|---|---|---|
Vis en liste over indlæg | få | / indlæg | indlæg#indeks |
Vis et indlæg | få | / indlæg/:id | indlæg#Vis |
Vis siden for at oprette indlæg | få | / indlæg / ny | indlæg#ny |
Opret et indlæg | indlæg | / indlæg | indlæg#Opret |
Vis siden for at redigere et indlæg | få | / indlæg/: id / Rediger | indlæg#Rediger |
Opdater et indlæg | PUT / PATCH | / indlæg/: id | indlæg#opdatering |
Slet et indlæg | slet | / indlæg/:id | indlæg#ødelægge |
vi kan ændre post
– delen af vores nuværende routing for at følge denne konvention:
# 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
Bemærk, at med dette nye mønster er der meget mindre verb i selve URL ‘ en, men vi stoler på HTTP-verbene (GET
/POST
/PUT
/PATCH
/DELETE
) at levere semantikken til ellers samme URL-mønstre, for eksempel /posts/:id
.
Bemærk, at PUT
var blevet brugt til opdatering af ressourcer indtil for nylig, da PATCH
blev bestemt til at være et bedre semantisk match for denne handling. Siden da har Rails flyttet til at foretrække PATCH
, men tillader begge verb til opdateringer.
en anden ændring, vi vil se senere, er, at vi vil dirigere alle URL ‘ er relateret til indlæg til en PostsController
i stedet for at håndtere alt i ApplicationController
. De PostController
‘s action navne
- ny
- indeks
- Vis
- Opret
- Rediger
- opdatering
- destroy
er også konventioner svarende til 7 interaktion mønstre.
dette er det stærkeste sæt konventioner, som Rails pålægger dig som applikationsudvikler. Vi beder dig om at gøre en indsats for at huske det. Vi vil gennemgå dette mange gange i hele bogen for at hjælpe dig med at gøre det også.
Routing for flere ressourcer
ofte skal vi have flere ressourcer til stede i URL ‘ en. For eksempel til vores blog-app, når vi har brug for en rute til at oprette en kommentar, er det meget vigtigt, at vi ved, hvilket indlæg denne kommentar oprettes på.
vi gør i øjeblikket dette:
post 'create_comment_for_post/:post_id' => 'application#create_comment'
Rails-konventionen for en URL med flere tilknyttede ressourcer er at starte med den “indeholdende” ressource helt til den “inderste” ressource. For eksempel vil vores ruter til kommentarer ændre sig til:
post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' get '/comments' => 'comments#index'
semantikken i disse URL ‘ er repræsenterer: “Opret en kommentar under et specifikt indlæg” og “Slet en kommentar under et specifikt indlæg”. Den sidste rute,” Vis alle kommentarer i systemet”, behøver ikke at være” scoped “under et indlæg, så URL ‘ en behøver ikke at føre med”/indlæg”.
hvis vi skal have flere ressourcer i URL ‘en med deres id’ er, er konventionen sådan, at den sidste ressource vil bruge pladsholderen :id
og resten vil være :resource_id
som :post_id
.
Restful
REST står for “Representational State Transfer”. Det er en arkitekturstil og retningslinje for at skabe skalerbare internettjenester. REST, som en måde at strukturere internetapplikationer på, har mange facetter til det, men lad os bare se på, hvordan det gælder for den grænseflade, Vi bruger til at interagere med Internetapps, URL ‘ erne.
for at se, hvordan hvile forenkler semantikken i URL ‘ er, lad os gå gennem et eksempel. Lad os sige, at vi bygger en online bestillingstjeneste. En na-larvve-implementering af tjenestens grænseflader (URL ‘er) 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
et afslappende interface design ville se sådan ud:
GET /orders/2 POST /orders GET /pizzas/1 POST /orders/12/payments DELETE /orders/3 POST /orders/13/expeditions
du kan se, afslappende grænseflader centrerer omkring “substantiver” eller “ressourcer”, fjerne “verb” fra grænsefladerne, men i stedet stole på de standardiserede HTTP-verb (GET
/POST
/PUT
/DELETE
) at levere rå semantik til aktionerne. Verber såsom check
, place
, cancel
er kortlagt direkte til HTTP verber af GET
at hente, POST
at oprette, og DELETE
at ødelægge ressource order
. pay
og expedite
er struktureret som oprettelse (HTTP POST) af underressourcer på payments
og expeditions
under ressource orders
.
RESTful interfaces standardiserede interaktionsmønstre for at gøre dem lettere at forstå og programmere imod. Fordi grænsefladerne er centreret omkring manipulering af ressourcer, er svarene meget mere forudsigelige. En analogi af, hvordan det afslappende arkitekturmønster forenkler interaktionen med internettjenester, ville være, hvordan Relationsdatabasen og sprogets sprog forenkler datalagring. Data blev typisk gemt i proprietære systemer med specifik logik for at interagere med dem, hvilket betød, at du på hvert projekt skulle lære et andet sæt instruktioner for at interagere med data. En fælles datastruktur (dataposter som rækker og kolonner gemt i tabeller) og et sæt fælles grænseflader – fire enkle verber af SELECT
, INSERT
, UPDATE
og DELETE
der kan understøtte alle typer applikationer.
vedtagelse af en afslappende grænseflade til din internetapp vil også strømline din applikation for at tilpasse sig, hvordan backend-dataene gemmes i databaser, og gør udviklingen lettere. Det får vi at se i de følgende kapitler.
Resource Notation
vi har talt om Rails’ routing konventioner, og afslappende URL mønstre. Nu vil vores routes.rb
fil se ud 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 ruterne som det, vi har i posts
sektionen meget almindelige, så Rails giver en særlig resources
notation, der hjælper med at generere dem til dig.
vi kan simpelthen gøre:
resources :posts
denne linje genererer automatisk de 8 linjer, vi havde før. Bemærk, at for handlingen update
tillader Rails både PUT
og PATCH
verb af kompatibilitetsårsager.
du kan køre bundle exec rake routes
i dit kommandolinjemiljø for at kontrollere, at det genererer nøjagtigt det samme sæt ruter.
Bemærk, at denne enkelt linje vil generere 8 ruter. I vores tilfælde har vi tilfældigvis brug for alle ruterne her, men hvis du kun har brug for en delmængde af ruterne, kan du definere dem mere eksplicit som:
resources :posts, only:
denne linje ovenfor vil kun generere 3 ruter til dig – Skriv bundle exec rake routes
for at tjekke det ud.
indlejrede ressourcer
Rails giver os også mulighed for at rede ressourcer til at oprette URL-mønstre med flere ressourcer, se nedenfor:
### config/routes.rb ### Rails.application.routes.draw do resources :posts do resources :comments, only: end resources :comments, only: :index end
Kør bundle exec rake routes
og se output – det skal være det samme som det, vi havde før.
Stihjælpere
når du kører bundle exec rake routes
, skal du bemærke kolonnen Prefix
for nogle af disse ruter. Disse er her for at hjælpe os med at vide, hvordan vi bruger Rails’ leverede stihjælpere til vores ruter. Vi kan bruge disse præfikser efterfulgt af _path
i vores controllere og visninger til let at bygge stier.
for eksempel:
posts_path # => '/posts' post_id = 123 post_comments_path(post_id) # => '/posts/123/comments'
Hvad er fordelen ved at bruge URL-hjælpere, snarere end hård kodning af stierne som /posts/123/comments
direkte i din kode? (for eksempel i din controller handling?) Årsagen til, at du vil bruge stihjælpere, er, at hvis du vil ændre URL – mønstrene i din app, er det meget lettere at bruge URL – hjælperne til at returnere en anden sti-lad os se på et eksempel:
get '/register', to: 'users#new', as: 'register'
når vi tilføjer “som” – klausulen til denne rute, hvis du kører bundle exec rake routes
, vil du se kolonnen Prefix
med register
, og du kan bruge register_path
til at få /register
stien. Nu, hvis vi vil ændre stien til /login
, er alt, hvad vi skal gøre, bare at:
get '/login', to: 'users#new', as: 'register'
nu giver vores register_path
os /login
. Vi behøver slet ikke ændre vores kode i Rails-appen.
flere Routingkonventioner
før vi går videre, lad os se hurtigt på et par variationer af det, vi allerede har set, samt nogle andre funktioner, der er tilgængelige for os 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
lad os nedbryde alle de funktioner, der er anført ovenfor en ad gangen.
-
root:
root
bruges til at angive, hvad handling kort til “/”(øverste niveau URL af vores hjemmeside, som ikke har nogen sti).Rod-URL ‘ en til din hjemmeside/app er den mest anvendte, på grund af detteroot
skal specificeres øverst i rutefilen. -
match + via:
match
bruges til at matche URL-mønstre til en eller flere ruter. Vi kan også specificere, hvilket HTTP-verbum der kan bruges til at matche til en URL med dette mønster. Vi gør dette ved at overføre en hash tilmatch
– metoden. Nøglen til denne hash ervia
, og værdien er en række HTTP-verb.match
er en mere generel form for nogle mere almindeligt anvendte HTTP routing metoder, såsomget
,post
ogdelete
. Det kan tage alle de samme muligheder som disse metoder, men sammenlignet med disse metoder giver det lidt mere fleksibilitet.
for eksempel ved at brugematch
kan vi angive en URL, der matcher for to forskellige ruter, der hver svarer til to forskellige HTTP-verber. Normalt ville det kræve to kommandoer i stedet for en. Vi kan se dette fra vores eksempel ovenfor, hvor vi matcher URL-mønsteret'/authors/:id'
til handlingen'authors#update'
. Vi specificerer derefter, hvilke HTTP-verb der kan bruges til at udstede anmodningen om den URL medvia:
. Angiv altid en HTTP-metode, når du brugermatch
, hvis du ikke gør det, kan det have negative konsekvenser for din applikations sikkerhed.
match
præsenterer en anden mulighed for routing til bestemte handlinger i Skinner. Generelt er det bedst at holde sig til de mere almindeligt anvendteHttpHelpers
metoder, såsomget
ogpost
. -
as: vi nævnte lidt tidligere, at indstillingen
as:
kan bruges sammen med vores rutedeklaration til at ændrepræfikset for vores URL-hjælpere. Dette kan bruges på forskellige måder. Vi kan brugeas:
til at gøre vores URL-hjælpere bedre til at matche brugerdefinerede URL ‘ er. En anden anvendelse er at ændre den aktuelle URL path helper til noget mere intuitivt eller noget, der matcher bedre med ressourcerne i en applikation. -
samlingsrute: se, hvordan vi ovenfor hekker vores
/popular
rute under ressourcenposts
. Vi bruger derefteron: :collection
til at specificere, hvilken del af en ressource vi hekker denne rute under. Vi har mange indlæg, så det betragtes som en samling. Ved at angiveon: :collection
siger vi: “Match en URL med sti/posts/popular
.”Hvis vi ikke tilføjedeon: :collection
, antager Rails, at denne rute svarer til en anden ressource, der er knyttet til et enkelt medlem af vores indlægssamling. I så fald ville vores rute blive/posts/:id/popular
. Vi kan også specificere flere indsamlingsruter ved hjælp af et blokformat.
collection do get 'popular' end
- passerer en ekstra parameter: vi kan angive en standardparameter, der altid bliver sendt ind med vores
params
hash, når vi matches med visse URL ‘ er. Der er to måder at specificere dette på; en måde er den samme måde, som vi gør ovenfor:
get 'popular', on: :collection, action: :index, popular: true
popular: true
vil blive videregivet til vores handling, som den populære rute matcher med via params
hash. Det vil have en nøgle på :popular
og en værdi på true
. Vi kan også bruge mere eksplicit syntaks ved at sende en hash til vores rutemetode get
, hvornøglen er defaults:
, og værdien er en anden hash, der indeholder navnet på den parameter, vi vil videregive til vores handling.
get 'popular', on: :collection, action: :index, defaults: { popular: true}
-
medlemsrute: vi kan bruge
on: member
til at angive, at vores rute matcher et medlem af en samling. Hvis vi bruger dette, vises det dynamiske segment som:id
. En URL-hjælper vil også blive oprettet sompreview_post
. Ved at angive denne rute medon: member
fortæller vi Rails, at dette er medlem af denne særlige ressource. At det ikke kun er en anden ressource indlejret under indlæg, men tættere knyttet eller relateret til vores indlæg i denne applikation. Flere medlemsruter kan defineres ved hjælp af et blokformat; dette format bruger den samme syntaks som blokformatet til at definere flere samlingsruter, bare erstatcollection
medmember
. -
omdirigering: der er et andet koncept at tale om, der vises i vores eksempel ovenfor, og det er omdirigering. Rails giver os mulighed for at omdirigere fra en sti til en anden ved hjælp af en omdirigering hjælper i forbindelse med en rute.
get '/home', to: redirect('/')
. Hvis nogen forsøger at få adgang til stien/home
, omdirigeres de strakstil rodstien/
. Dette er ikke begrænset til kun en URL-sti selvfølgelig; vi kunne også have noget som dette:get '/home', to: redirect('/travel')
.
anmeldelse
Rails ruter står foran et program. En rute fortolker en indgående HTTP-anmodning og:
- matcher en anmodning til en controller-handling baseret på kombinationen af et HTTP-verbum og forespørgsels-URL-mønsteret
- indfanger data i URL ‘ en for at være tilgængelig i
params
i controller-handlinger - Rails opfordrer udviklere til at bruge afslappende URL-mønstre, når de opretter ruter, med konceptualisering af manipulering af ressourcer med HTTP-verb.
- du kan bruge makroen
resources
til at generere afslappende ruter meget hurtigt.