Rute și resurse

convenții de rutare de bază

să aruncăm o privire la rutele noastre așa cum sunt acum, folosind 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 

una dintre informațiile cheie pentru convențiile Rails este că aplicațiile centrate pe date (sau aplicațiile grosolane) tind să aibă modalități foarte similare pentru a permite utilizatorilor să interacționeze cu aplicația, care sunt:

  • o pagină pentru a vizualiza o listă cu ceva
  • vizualizați ceva
  • afișați un formular pentru a crea o nouă instanță a ceva
  • creați de fapt ceva
  • afișați un formular pentru a edita o instanță a ceva
  • actualizați de fapt ceva
  • ștergeți ceva

aceste șapte „modele de interacțiune” sunt atât de comune, încât rails oferă un set puternic de convenții de la rutare la controlere, vizualizări și formulare pentru a ajuta la simplificarea acestor fluxuri de lucru. Ne vom concentra pe partea de rutare acum.

pentru rutare, convenția este că, în loc să fim nevoiți să venim cu modelele URL, Rails recomandă să structurăm adresele URL și acțiunile controlerului corespunzător în felul următor:

flux de lucru HTTP VERB cale Controller de acțiune
arată o listă de posturi obține / posturi posturi # index
arată o postare obține / postări/:id mesaje # spectacol
arată pagina pentru a crea mesaj obține / mesaje / nou mesaje#nou
creați o postare postare / postări postări # crea
arată pagina pentru a edita o postare obține / postări/: id / editare postări#editare
actualizați o postare PUT / PATCH / postări/: id postări#actualizare
șterge o postare șterge / postări/:id-ul posturi # distruge

putem schimba partea post a rutării noastre actuale pentru a urma această convenție:

# 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 

și în fișierul 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 

observați că, cu acest nou model, există mult mai puține verbe în URL-ul în sine, dar ne bazăm pe verbele HTTP(GET/POST/PUT/PATCH/DELETE) pentru a furniza semantica pentru aceleași modele URL, de exemplu /posts/:id.

rețineți că PUT a fost folosit pentru actualizarea resurselor până de curând, când PATCH a fost determinat să fie o potrivire semantică mai bună pentru această acțiune. De atunci, Rails a trecut la prefering PATCH, dar permițând ambele verbe pentru actualizări.

o altă modificare pe care o vom vedea mai târziu este că vom direcționa toate adresele URL legate de postări către un PostsControllerîn loc să gestionăm totul în ApplicationController. Numele acțiunii PostController

  • new
  • index
  • show
  • create
  • edit
  • update
  • destroy

sunt, de asemenea, convenții corespunzătoare interacțiunii 7 modele.

acesta este cel mai puternic set de convenții pe care Rails le impune ca dezvoltator de aplicații. Vă vom cere să faceți un efort pentru a-l memora. Vom revedea acest lucru de multe ori pe parcursul cărții pentru a vă ajuta să faceți și asta.

rutare pentru mai multe resurse

deseori trebuie să avem mai multe resurse prezente în URL. De exemplu, pentru aplicația noastră de blog ori de câte ori trebuie să avem o rută pentru a crea un comentariu, este foarte important să știm pe ce postare este creat acest comentariu.

în prezent facem asta:

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

Convenția Rails a unei adrese URL cu mai multe resurse asociate este de a începe cu resursa „care conține” până la resursa „cea mai interioară”. De exemplu, rutele noastre pentru comentarii s-ar schimba în:

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

semantica acestor adrese URL reprezintă: „creați un comentariu sub o anumită postare” și „ștergeți un comentariu sub o anumită postare”. Ultima rută, „afișați toate comentariile din sistem”, nu trebuie să fie” scoped „sub o postare, astfel încât adresa URL nu trebuie să conducă cu”/postări”.

dacă trebuie să avem mai multe resurse în URL cu ID-urile lor, convenția este de așa natură încât ultima resursă va folosi substituentul :id și toate celelalte vor fi :resource_idcum ar fi :post_id.

Restful

REST înseamnă „transfer de Stat reprezentativ”. Este un stil de Arhitectură software și orientare pentru a crea servicii web scalabile. REST, ca modalitate de structurare a aplicațiilor web, are multe fațete, dar să ne uităm doar la modul în care se aplică interfeței pe care o folosim pentru a interacționa cu aplicațiile web, adresele URL.

pentru a vedea cum REST simplifică semantica adreselor URL, să parcurgem un exemplu. Să presupunem că construim un serviciu online de comandă a pizza. A na punerea în aplicare a interfețelor serviciului (URL-uri) ar fi:

/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 

un design de interfață odihnitor ar arăta astfel:

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

puteți vedea, interfețele odihnitoare se concentrează în jurul „substantivelor” sau „resurselor”, eliminând „verbele” din interfețe, dar bazându – se în schimb pe verbele HTTP standardizate(GET/POST/PUT/DELETE) pentru a furniza semantică crudă pentru acțiuni. Verbe precum check, place, cancel sunt mapate direct la verbele HTTP de GET pentru a prelua, POST pentru a crea și DELETEpentru a distruge resursa order. pay și expedite sunt structurate ca crearea (HTTP POST) de sub resurse de payments și expeditions sub resursă orders.

interfețe RESTful modele standardizate de interacțiune aplicație web pentru a le face mai ușor de înțeles și de program împotriva. Deoarece interfețele sunt centrate în jurul manipulării resurselor, răspunsurile sunt mult mai previzibile. O analogie a modului în care modelul arhitecturii RESTful simplifică interacțiunea cu serviciile web ar fi modul în care baza de date relațională și limbajul SQL simplifică stocarea datelor. Înainte de baza de date relațională și SQL, datele erau de obicei stocate în sisteme proprietare cu logică specifică pentru a interacționa cu ele, ceea ce însemna că la fiecare proiect va trebui să înveți un set diferit de instrucțiuni pentru a interacționa cu datele. Bazele de date relaționale și SQL au dat o structură de date comună (înregistrări de date ca rânduri și coloane stocate în tabele) și un set de interfețe comune-patru verbe simple ale SELECT, INSERT, UPDATE și DELETE care poate suporta toate tipurile de aplicații.

adoptarea unei interfețe RESTful pentru aplicația dvs. web va simplifica, de asemenea, aplicația dvs. pentru a se alinia la modul în care datele backend sunt stocate în bazele de date și facilitează dezvoltarea. Vom vedea asta în capitolele următoare.

notație de resurse

am vorbit despre convențiile de rutare Rails, și modele URL odihnitor. Acum fișierul nostru routes.rb ar arăta ca următorul:

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

de fapt, rutele ca ceea ce avem în secțiunea posts sunt foarte frecvente, astfel încât Rails oferă o notație specială resources care ajută la generarea celor pentru dvs.

putem face pur și simplu:

resources :posts 

această linie va genera automat cele 8 linii pe care le-am avut înainte. Rețineți că pentru acțiunea update, Rails permite atât verbul PUT, cât și verbul PATCH, din motive de compatibilitate.

puteți rula bundle exec rake routes în mediul liniei de comandă pentru a verifica dacă generează exact același set de rute.

rețineți că această singură linie va genera 8 rute. În cazul nostru se întâmplă să avem nevoie de toate rutele aici, dar dacă aveți nevoie doar de un subset al rutelor, le puteți defini mai explicit ca:

resources :posts, only: 

această linie de mai sus ar genera doar 3 rute pentru dvs. – tastați bundle exec rake routes pentru a o verifica.

resurse imbricate

șine, de asemenea, ne permite să Resurse cuib pentru a crea modele URL cu mai multe resurse, a se vedea mai jos:

### config/routes.rb ### Rails.application.routes.draw do resources :posts do resources :comments, only: end resources :comments, only: :index end 

rulați bundle exec rake routes și vedeți ieșirea-ar trebui să fie la fel ca ceea ce am avut înainte.

ajutoare de cale

când executați bundle exec rake routes, observați coloana Prefix pentru unele dintre aceste rute. Acestea sunt aici pentru a ne ajuta să știm cum să folosim ajutoarele de cale furnizate de șine pentru rutele noastre. Putem folosi aceste prefixe urmate de _path în controlerele și vizualizările noastre pentru a construi cu ușurință căi.

de exemplu:

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

care este avantajul utilizării ajutoarelor URL, Mai degrabă decât codarea dură a căilor, cum ar fi /posts/123/comments direct în codul dvs.? (de exemplu, în acțiunea controlerului?) Motivul pentru care doriți să utilizați path helpers este că, dacă doriți să modificați modelele URL din aplicația dvs., este mult mai ușor să utilizați helpers URL pentru a returna o altă cale – să ne uităm la un exemplu:

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

când adăugăm clauza” ca ” la această rută, dacă executați bundle exec rake routes, veți vedea coloana Prefix cu register și puteți utiliza register_path pentru a obține /register calea. Acum, dacă vrem să schimbăm calea către /login , tot ce trebuie să facem este doar să:

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

acum register_path ne dă /login. Nu trebuie să ne schimbăm deloc codul în aplicația Rails.

mai multe convenții de rutare

înainte de a merge mai departe, să aruncăm o privire rapidă la câteva variante de ceea ce am văzut deja, precum și alte caracteristici disponibile pentru noi în 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 

să descompunem toate caracteristicile enumerate mai sus pe rând.

  • root: root este folosit pentru a specifica ce acțiune mapează la „/”(URL-ul de nivel superior al site-ului nostru care nu are cale).URL-ul rădăcină al site-ului/aplicației dvs. este cel mai frecvent utilizat, din această cauză root ar trebui specificatîn partea de sus a fișierului rute.

  • meci + via: match este folosit pentru a potrivi modele URL la una sau mai multe rute. De asemenea, putem specifica ce verb HTTP poate fi utilizat pentru potrivirea la o adresă URL cu acest model. Facem acest lucru prin trecerea într-un hash la match metoda. Cheia pentru acest hash este via, iar valoarea este o serie de verbe HTTP. match este o formă mai generală a unor metode de rutare HTTP mai frecvent utilizate, cum ar fi get, postși delete. Se poate lua toate aceleași opțiuni ca aceste metode, dar, în comparație cu aceste metode, oferă un pic mai multă flexibilitate.
    de exemplu, folosind match putem specifica un URL care se potrivește pentru două rute diferite, fiecare corespunzând la două verbe HTTP diferite. În mod normal, acest lucru ar necesita două comenzi, în loc de una. Putem vedea acest lucru din exemplul nostru de mai sus, unde potrivim modelul URL '/authors/:id' cu acțiunea 'authors#update'. Apoi specificăm ce verbe HTTP pot fi utilizate pentru a emite cererea pentru acea adresă URL cu via: . Specificați întotdeauna o metodă HTTP atunci când utilizați match, acest lucru poate avea implicații negative asupra securității aplicației.
    match prezintă o altă opțiune pentru rutare la anumite acțiuni în șine. În general, cel mai bine este să rămânem cu cele mai utilizate metode HttpHelpers, cum ar fi get și post.

  • as: am menționat un pic mai devreme că opțiunea as: poate fi utilizată cu declarația noastră de traseu pentru a schimba prefixul pentru ajutoarele noastre URL. Acest lucru poate fi folosit în diferite moduri. Putem folosi as: pentru a face ca ajutoarele noastre URL să se potrivească mai bine cu adresele URL personalizate. O altă utilizare este de a schimba calea URL curentă helper la ceva mai intuitiv sau ceva care se potrivește mai bine cu resursele dintr-o aplicație.

  • traseu de colectare: vedeți cum mai sus ne cuibărim traseul /popular sub resursa posts. Apoi folosim on: :collection pentru a specifica sub ce parte a unei resurse cuibărim această rută. Avem multe postări, astfel încât este considerată o colecție. Specificând on: :collection spunem: „potriviți o adresă URL cu calea /posts/popular.”Dacă nu am adăugat on: :collection, Rails va presupune că această rută corespunde unei alte resurse asociate cu un singur membru al colecției noastre de postări. În acest caz, traseul nostru ar deveni /posts/:id/popular. De asemenea, putem specifica mai multe rute de colectare utilizând un format bloc.

collection do get 'popular' end 
  • trecerea unui parametru suplimentar: putem specifica un parametru implicit care este întotdeauna transmis cu hash-ul nostru params atunci când suntem potriviți cu anumite adrese URL. Există două moduri de a specifica acest lucru; o cale este același mod în care facem mai sus:
get 'popular', on: :collection, action: :index, popular: true 

popular: true va fi trecut la acțiunea noastră că traseul popular se potrivește cu prin intermediul hash-ului params. Va avea o cheie de :popular și o valoare de true. De asemenea, putem folosi o sintaxă mai explicită trecând un hash la metoda noastră de traseu get, undecheia este defaults: iar valoarea este un alt hash care conține numele parametrului pe care dorim să-l transmitem acțiunii noastre.

get 'popular', on: :collection, action: :index, defaults: { popular: true} 
  • traseu membru: putem folosi on: member pentru a specifica că traseul nostru se potrivește cu un membru al unei colecții. Dacă vom folosi acest segment dinamic va apărea ca :id. Un ajutor URL va fi, de asemenea, creat ca preview_post. Specificând această rută cu on: member, îi spunem lui Rails că acesta este un membru al acestei resurse. Că nu este doar o altă resursă imbricată sub postări, ci mai strâns legată sau legată de postările noastre din această aplicație. Mai multe rute membre pot fi definite folosind un format bloc; acest format folosește aceeași sintaxă ca formatul bloc pentru definirea mai multor rute de colectare, trebuie doar să înlocuiți collection cu member.

  • redirecționare: există un alt concept despre care să vorbim care este afișat în exemplul nostru de mai sus și acesta este redirecționarea. Rails ne oferă capacitatea de a redirecționa de la o cale la alta folosind un ajutor de redirecționare împreună cu un traseu.get '/home', to: redirect('/'). Dacă cineva încearcă să acceseze calea /home, va fi redirecționat imediat la calea rădăcină /. Acest lucru nu este limitat la o singură cale URL, desigur; am putea avea și așa ceva: get '/home', to: redirect('/travel').

revizuirea

șine rute stau în fața unei aplicații. Un traseu interpretează o cerere HTTP de intrare și:

  • potrivește o cerere la o acțiune controler bazat pe combinația dintre un verb HTTP și modelul URL cerere
  • surprinde date în URL-ul pentru a fi disponibile în params în acțiuni controler
  • Rails încurajează dezvoltatorii să utilizeze modele URL RESTful atunci când Configurarea rute, cu Conceptualizarea de manipulare a resurselor cu verbe HTTP.
  • puteți utiliza macrocomanda resources pentru a genera rute odihnitoare foarte repede.

Lasă un răspuns

Adresa ta de email nu va fi publicată.