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_id
cum 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 DELETE
pentru 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 lamatch
metoda. Cheia pentru acest hash estevia
, 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 figet
,post
șidelete
. 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, folosindmatch
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 cuvia:
. Specificați întotdeauna o metodă HTTP atunci când utilizațimatch
, 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 metodeHttpHelpers
, cum ar figet
șipost
. -
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 folosias:
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 resursaposts
. Apoi folosimon: :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ândon: :collection
spunem: „potriviți o adresă URL cu calea/posts/popular
.”Dacă nu am adăugaton: :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 capreview_post
. Specificând această rută cuon: 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țicollection
cumember
. -
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.