Ruter og ressourcer

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 / indlæg indlæg#indeks
Vis et indlæg / indlæg/:id indlæg#Vis
Vis siden for at oprette indlæg / 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 / 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 PostsControlleri 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_idsom :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 DELETEat ø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 dette root 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 til match – metoden. Nøglen til denne hash er via, og værdien er en række HTTP-verb. match er en mere generel form for nogle mere almindeligt anvendte HTTP routing metoder, såsom get, postog delete. Det kan tage alle de samme muligheder som disse metoder, men sammenlignet med disse metoder giver det lidt mere fleksibilitet.
    for eksempel ved at bruge match 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 med via: . Angiv altid en HTTP-metode, når du bruger match, 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 anvendte HttpHelpers metoder, såsom get og post.

  • 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 bruge as: 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 ressourcen posts. Vi bruger derefter on: :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 angive on: :collection siger vi: “Match en URL med sti /posts/popular.”Hvis vi ikke tilføjede on: :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å :popularog 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 som preview_post. Ved at angive denne rute med on: 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 erstat collection med member.

  • 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 iparams 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.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.