Rutter och resurser

grundläggande Routingkonventioner

Låt oss ta en titt på våra rutter som de är nu, med hjälp avrake 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 viktigaste insikterna för Rails-konventioner är att datacentrerade appar (eller grova appar) tenderar att ha mycket liknande sätt att låta användare interagera med applikationen, som är:

  • en sida för att visa en lista med något
  • visa något
  • visa ett formulär för att skapa en ny instans av något
  • skapa faktiskt något
  • visa ett formulär för att redigera en instans av något
  • uppdatera faktiskt något
  • ta bort något

dessa sju ”interaktionsmönster” är så vanliga, att rails ger en stark uppsättning konventioner från routing till controllers, vyer och former för att göra dessa arbetsflöden enklare. Vi kommer att fokusera på routingdelen nu.

för routing är konventionen att istället för att vi måste komma med URL-mönstren rekommenderar Rails att vi strukturerar webbadresserna och motsvarande kontrollåtgärder på följande sätt:

arbetsflöde HTTP-VERB sökväg kontrollåtgärd
visa en lista med inlägg / inlägg inlägg # index
visa ett inlägg / inlägg/:id inlägg # visa
Visa sidan för att skapa inlägg / inlägg / nytt inlägg # nytt
skapa ett inlägg inlägg / inlägg inlägg # skapa
Visa sidan för att redigera ett inlägg / inlägg/: id / redigera inlägg # redigera
Uppdatera ett inlägg PUT / PATCH / inlägg/: id inlägg # uppdatering
radera ett inlägg radera / inlägg/:id inlägg # förstöra

vi kan ändra post – delen av vår nuvarande routing för att följa denna 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 

och i filen 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 later.. ... end 

Lägg märke till att med det här nya mönstret finns det mycket mindre verb i själva webbadressen, men vi litar på HTTP-verben (GET/POST/PUT/PATCH/DELETE) för att leverera semantiken för annars samma URL-mönster, till exempel /posts/:id.

Observera att PUT hade använts för att uppdatera resurser tills nyligen, när PATCH bestämdes vara en bättre semantisk matchning för denna åtgärd. Sedan dess har Rails flyttat till att föredra PATCH, men tillåter båda verben för uppdateringar.

en annan ändring som vi kommer att se senare är att vi kommer att dirigera alla webbadresser relaterade till inlägg till en PostsController istället för att hantera allt i ApplicationController. PostController åtgärdsnamn

  • nytt
  • index
  • visa
  • skapa
  • redigera
  • uppdatera
  • förstör

är också konventioner som motsvarar 7-interaktionen mönster .

Detta är den starkaste uppsättning konventioner som Rails ålägger dig som applikationsutvecklare. Vi ber dig att göra ett försök att memorera det. Vi kommer att återkomma detta många gånger i hela boken för att hjälpa dig att göra det också.

Routing för flera resurser

ofta måste vi ha flera resurser som finns i webbadressen. Till exempel för vår bloggapp när vi behöver ha en rutt för att skapa en kommentar är det mycket viktigt att vi vet vilket inlägg den här kommentaren skapas på.

vi gör för närvarande detta:

post 'create_comment_for_post/:post_id' => 'application#create_comment' 

Rails-konventionen för en URL med flera associerade resurser är att börja med den ”innehållande” resursen hela vägen till den ”innersta” resursen. Till exempel skulle våra vägar för kommentarer ändras till:

post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' get '/comments' => 'comments#index' 

semantiken för dessa webbadresser representerar:” skapa en kommentar under ett specifikt inlägg ”och”ta bort en kommentar under ett specifikt inlägg”. Den sista rutten, ”visa alla kommentarer i systemet”, behöver inte vara ”scoped” under ett inlägg, så webbadressen behöver inte leda med ”/inlägg”.

om vi behöver ha flera resurser i webbadressen med deras ID, är konventionen sådan att den sista resursen kommer att använda platshållaren :id och resten kommer att vara :resource_id som :post_id.

Restful

REST står för ”Representational State Transfer”. Det är en mjukvaruarkitektur stil och riktlinje för att skapa skalbara webbtjänster. Vila, som ett sätt att strukturera webbapplikationer, har många aspekter på det, men låt oss bara titta på hur det gäller gränssnittet som vi använder för att interagera med webbappar, webbadresserna.

för att se hur REST förenklar semantiken för webbadresser, låt oss gå igenom ett exempel. Låt oss säga att vi bygger en online pizza beställningstjänst. En na-implementering av gränssnitten för tjänsten (URL: er) skulle vara:

/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 vilsam gränssnittsdesign skulle se ut så här:

GET /orders/2 POST /orders GET /pizzas/1 POST /orders/12/payments DELETE /orders/3 POST /orders/13/expeditions 

du kan se, vilsamma gränssnitt centrerar kring ”substantiv” eller ”resurser”, tar bort ”verb” från gränssnitten men förlitar sig istället på de standardiserade HTTP-verben (GET/POST/PUT/DELETE) att leverera CRUD semantik för åtgärderna. Verb som check, place, cancel mappas direkt till HTTP-verb av GET för att hämta, POST för att skapa och DELETEför att förstöra resurs order. pay och expedite är strukturerade som skapande (HTTP POST) av underresurser av payments och expeditions under resurs orders.

RESTful interfaces standardiserade interaktionsmönster för webbapplikationer för att göra dem lättare att förstå och programmera mot. Eftersom gränssnitten är centrerade kring att manipulera resurser är svaren mycket mer förutsägbara. En analogi av hur RESTful architecture-mönstret förenklar interaktionen med webbtjänster skulle vara hur relationsdatabasen och SQL-språket förenklar datalagring. Innan relationsdatabas och SQL lagrades data vanligtvis i egna system med specifik logik för att interagera med dem, vilket innebar att du på varje projekt måste lära dig en annan uppsättning instruktioner för att interagera med data. Relationsdatabaser och SQL gav en gemensam datastruktur (dataposter som rader och kolumner lagrade i tabeller) och en uppsättning gemensamma gränssnitt – fyra enkla verb av SELECT, INSERT, UPDATE och DELETE som kan stödja alla typer av applikationer.

att anta ett vilsamt gränssnitt för din webbapp kommer också att effektivisera din applikation för att anpassa sig till hur backend-data lagras i databaser och underlättar utvecklingen. Vi får se det i följande kapitel.

Resursnotation

vi har pratat om Rails routingkonventioner och vilsamma URL-mönster. Nu skulle vår routes.rb – fil se ut som följande:

### 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 

faktum är att rutterna som vad vi har i avsnittet posts är mycket vanliga, så Rails ger en speciell resources notation som hjälper till att generera dem åt dig.

vi kan helt enkelt göra:

resources :posts 

denna linje genererar automatiskt de 8 linjerna vi hade tidigare. Observera att för åtgärden update tillåter Rails både PUT och PATCH verb, av kompatibilitetsskäl.

du kan köra bundle exec rake routes i din kommandoradsmiljö för att verifiera att den genererar exakt samma uppsättning rutter.

Observera att denna enda rad kommer att generera 8 rutter. I vårt fall behöver vi alla rutter här, men om du bara behöver en delmängd av rutterna kan du definiera dem mer uttryckligen som:

resources :posts, only: 

den här raden ovan skulle bara generera 3 rutter för dig – Skriv bundle exec rake routes för att kolla in den.

kapslade resurser

Rails tillåter oss också att bo resurser för att skapa URL-mönster med flera resurser, se nedan:

### 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 och se utgången – den ska vara densamma som vad vi hade tidigare.

Path Helpers

när du kör bundle exec rake routes, Lägg märke till kolumnen Prefix för några av dessa rutter. Dessa är här för att hjälpa oss att veta hur man använder Rails tillhandahållna väghjälpare för våra rutter. Vi kan använda dessa prefix följt av _path i våra kontroller och vyer för att enkelt bygga vägar.

till exempel:

posts_path # => '/posts' post_id = 123 post_comments_path(post_id) # => '/posts/123/comments' 

Vad är fördelen med att använda URL-hjälpare, snarare än hårdkodning av sökvägar som /posts/123/comments direkt i din kod? (till exempel i din controller action?) Anledningen till att du vill använda sökvägshjälpare är att om du vill ändra URL-mönstren i din app är det mycket lättare att använda URL-hjälparna för att returnera en annan sökväg-låt oss titta på ett exempel:

get '/register', to: 'users#new', as: 'register' 

när vi lägger till ”as” – klausulen till den här rutten, om du kör bundle exec rake routes, ser du kolumnen Prefix med register, och du kan använda register_path för att få /register sökvägen. Nu, om vi vill ändra sökvägen till /login, behöver vi bara göra:

get '/login', to: 'users#new', as: 'register' 

nu ger vår register_path oss /login. Vi behöver inte ändra vår kod i Rails-appen alls.

fler Routingkonventioner

innan vi går vidare, Låt oss ta en snabb titt på ett par varianter av vad vi redan har sett, liksom några andra funktioner som är tillgängliga för 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 

låt oss bryta ner alla funktioner som anges ovan en i taget.

  • root: root används för att ange vilka åtgärdskartor till ”/”(den översta webbadressen till vår webbplats som inte har någon sökväg).Root-webbadressen till din webbplats/app är den vanligaste, på grund av detta root bör specificeras högst upp i ruttfilen.

  • match + via: match används för att matcha URL-mönster till en eller flera rutter. Vi kan också ange vilket HTTP-verb som kan användas för att matcha en URL med detta mönster. Vi gör detta genom att skicka in en hash till match – metoden. Nyckeln för denna hash är via, och värdet är en uppsättning HTTP-verb. match är en mer generell form av några mer vanliga HTTP-routingmetoder, såsom get, postoch delete. Det kan ta alla samma alternativ som dessa metoder, men jämfört med dessa metoder ger det lite mer flexibilitet.
    till exempel, genom att använda match kan vi ange en URL som matchar för två olika rutter, var och en motsvarar två olika HTTP-verb. Normalt skulle detta kräva två kommandon istället för en. Vi kan se detta från vårt exempel ovan, där vi matchar URL-mönstret '/authors/:id' till åtgärden 'authors#update'. Vi anger sedan vilka HTTP-verb som kan användas för att utfärda begäran om den webbadressen med via: . Ange alltid en HTTP-metod när du använder match, om du inte gör det kan det få negativa konsekvenser för programmets säkerhet.
    match presenterar ett annat alternativ för dirigering till vissa åtgärder i Rails. I allmänhet är det bäst att hålla fast vid de vanligaste HttpHelpers – metoderna, som get och post.

  • as: vi nämnde lite tidigare att alternativet as: kan användas med vår ruttdeklaration för att ändraprefixet för våra URL-hjälpare. Detta kan användas på olika sätt. Vi kan använda as: för att göra våra URL-hjälpare bättre matcha anpassade webbadresser. En annan användning är att ändra den aktuella URL – sökvägshjälpen till något mer intuitivt eller något som matchar bättre med resurserna i en applikation.

  • samlingsväg: se hur ovan Vi Bo vår /popular rutt under posts resurs. Vi använder sedan on: :collection för att ange vilken del av en resurs vi häckar denna rutt under. Vi har många inlägg så det anses vara en samling. Genom att ange on: :collection säger vi, ” matcha en URL med sökväg /posts/popular.”Om vi inte lägger till on: :collection, kommer Rails att anta att denna rutt motsvarar en annan resurs som är associerad med en enda medlem i vår postsamling. I så fall skulle vår rutt bli /posts/:id/popular. Vi kan också ange flera samlingsvägar med hjälp av ett blockformat.

collection do get 'popular' end 
  • passerar en extra parameter: vi kan ange en standardparameter som alltid får skickas in med vår params hash när vi matchas med vissa webbadresser. Det finns två sätt att specificera detta; ett sätt är på samma sätt som vi gör ovan:
get 'popular', on: :collection, action: :index, popular: true 

popular: true kommer att skickas till vår åtgärd som den populära rutten matchar med via params hash. Den kommer att ha en nyckel på :popular och ett värde på true. Vi kan också använda mer explicit syntax genom att skicka en hash till vår ruttmetod get, varnyckeln är defaults: och värdet är en annan hash som innehåller namnet på parametern vi vill överföra till vår åtgärd.

get 'popular', on: :collection, action: :index, defaults: { popular: true} 
  • medlemsrutt: vi kan använda on: member för att ange att vår rutt matchar en medlem i en samling. Om vi använder detta kommer det dynamiska segmentet att visas som :id. En URL-hjälpare kommer också att skapas som preview_post. Genom att ange denna rutt med on: member berättar vi Rails att detta är medlem i den här resursen. Att det inte bara är en annan resurs kapslad under inlägg, men närmare kopplad eller relaterad till våra inlägg i den här applikationen. Flera medlemsrutter kan definieras med ett blockformat; detta format använder samma syntax som blockformatet för att definiera flera samlingsrutter, ersätt bara collection med member.

  • omdirigering: det finns ett annat koncept att prata om som visas i vårt exempel ovan, och det är omdirigering. Rails ger oss möjlighet att omdirigera från en väg till en annan genom att använda en omdirigeringshjälpare i samband med en rutt.get '/home', to: redirect('/'). Om någon försöker komma åt sökvägen /home omdirigeras de omedelbart till rotvägen /. Detta är naturligtvis inte begränsat till bara en URL-sökväg; vi kan också ha något så här: get '/home', to: redirect('/travel').

Review

Rails rutter står framför en ansökan. En rutt tolkar en inkommande HTTP-begäran och:

  • matchar en begäran till en kontrolleråtgärd baserad på kombinationen av ett HTTP-verb och begäran URL-mönstret
  • fångar data i webbadressen för att vara tillgänglig iparams i kontrolleråtgärder
  • Rails uppmuntrar utvecklare att använda vilsamma URL-mönster när de konfigurerar rutter, med konceptualisering av att manipulera resurser med HTTP-verb.
  • du kan använda makrot resources för att generera vilsamma rutter mycket snabbt.

Lämna ett svar

Din e-postadress kommer inte publiceras.