Percorsi e risorse

Convenzioni di routing di base

Diamo un’occhiata ai nostri percorsi come sono ora, usando 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 delle informazioni chiave per le convenzioni Rails è che le app incentrate sui dati (o le app crudeli) tendono ad avere modi molto simili per consentire agli utenti di interagire con l’applicazione, che sono:

  • una pagina per visualizzare un elenco di qualcosa
  • cosa vista
  • mostra una maschera per creare una nuova istanza di qualcosa
  • effettivamente creare qualcosa di
  • visualizzare un form per la modifica di un’istanza di qualcosa
  • aggiorna effettivamente qualcosa
  • elimina qualcosa

Quei sette “modelli di interazione” sono così comuni, che Rails fornisce un insieme di convenzioni per il routing per i controller, idee e forme per contribuire a rendere questi flussi di lavoro più semplice. Ora ci concentreremo sulla parte di routing.

Per il routing, la convenzione è che invece di noi che hanno a venire con il pattern URL, Guide consiglia di struttura gli Url e le corrispondenti azioni di controller nel modo seguente:

Flusso di lavoro HTTP VERBO PERCORSO Controller Azione
Mostra un elenco dei post GET /post post#indice
Vedi un post GET /posts/:id post#mostra
Vedi la pagina per creare post GET /posts/nuovo post#nuovo
Creare un post POST /post post#creare
Mostra la pagina di modifica di un post GET /posts/:id/modifica post#modifica
l’Aggiornamento di un post PUT/PATCH /posts/id: post#aggiornamento
Eliminare un post ELIMINA /posts/:id post#distruggere

Siamo in grado di modificare il post parte della nostra corrente di routing per seguire questa convenzione:

# 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 

E nel routes.rb file,

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 

si Noti che con questo nuovo modello, ci sono un sacco di meno verbi nell’URL, ma stiamo contando sui verbi HTTP (GET/POST/PUT/PATCH/DELETE) per fornire la semantica per il resto schemi di URL, per esempio /posts/:id.

Si noti che PUT era stato utilizzato per aggiornare le risorse fino a poco tempo fa, quando PATCH era determinato per essere una corrispondenza semantica migliore per questa azione. Da allora, Rails è passato a preferire PATCH, ma consentendo entrambi i verbi per gli aggiornamenti.

Un’altra modifica che vedremo più avanti è che instraderemo tutti gli URL relativi ai post su un PostsControllerinvece di gestire tutto in ApplicationController. I nomi delle azioni PostController

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

sono anche convenzioni corrispondenti all’interazione 7 modelli.

Questo è il più forte insieme di convenzioni che Rails impone a voi come sviluppatore di applicazioni. Ti chiederemo di fare uno sforzo per memorizzarlo. Ci rivisiteremo questo un sacco di volte in tutto il libro per aiutarvi a farlo pure.

Routing per più risorse

Spesso abbiamo bisogno di avere più risorse presenti nell’URL. Ad esempio per la nostra app blog ogni volta che abbiamo bisogno di avere un percorso per creare un commento, è molto importante sapere su quale post viene creato questo commento.

Attualmente lo stiamo facendo:

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

La convenzione Rails di un URL con più risorse associate è di iniziare con la risorsa “contenente” fino alla risorsa “più interna”. Ad esempio, i nostri percorsi per i commenti cambierebbero in:

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

La semantica di tali URL rappresenta: “Crea un commento sotto un post specifico” e “elimina un commento sotto un post specifico”. L’ultimo percorso, “mostra tutti i commenti nel sistema”, non ha bisogno di essere “ambito” sotto un post, quindi l’URL non deve condurre con “/posts”.

Se abbiamo bisogno di avere più risorse nell’URL con i loro ID, la convenzione è tale che l’ultima risorsa utilizzerà il segnaposto :id e tutto il resto sarà :resource_idcome :post_id.

Restful

REST sta per “Representational State Transfer”. È uno stile di architettura software e una linea guida per creare servizi Web scalabili. REST, come un modo per strutturare le applicazioni web, ha molte sfaccettature ad esso, ma diamo solo un’occhiata a come si applica all’interfaccia che usiamo per interagire con le applicazioni web, gli URL.

Per vedere come REST semplifica la semantica degli URL, esaminiamo un esempio. Diciamo che stiamo costruendo un servizio di ordinazione di pizza online. Un’implementazione naïve delle interfacce del servizio (URL) sarebbe:

/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 di interfaccia RESTful sarebbe simile a questo:

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

Puoi vedere, le interfacce RESTful si concentrano su “nomi” o “risorse”, rimuovendo “verbi” dalle interfacce ma basandosi invece sui verbi HTTP standardizzati(GET/POST/PUT/DELETE) fornire semantica CRUD per le azioni. Verbi come check, place, cancel sono mappati direttamente ai verbi HTTP di GET per recuperare, POST per creare e DELETE per distruggere la risorsa order. pay e expedite sono strutturati come creazione (HTTP POST) di risorse secondarie di payments e expeditionssotto risorsa orders.

Interfacce RESTful modelli di interazione delle applicazioni Web standardizzati per renderli più facili da capire e programmare contro. Poiché le interfacce sono incentrate sulla manipolazione delle risorse, le risposte sono molto più prevedibili. Un’analogia di come il modello di architettura RESTful semplifica l’interazione con i servizi Web sarebbe il modo in cui il database relazionale e il linguaggio SQL semplificano l’archiviazione dei dati. Prima di Database relazionali e SQL, i dati sono stati in genere memorizzati in sistemi proprietari con logica specifica per interagire con loro, questo significava che su ogni progetto si avrebbe dovuto imparare un diverso insieme di istruzioni per interagire con i dati. Database relazionali e SQL ha dato una struttura dati comune (record di dati come righe e colonne memorizzate nelle tabelle) e un insieme di interfacce comuni-quattro semplici verbi di SELECT, INSERT, UPDATE e DELETE in grado di supportare tutti i tipi di applicazioni.

L’adozione di un’interfaccia RESTful per la tua app Web semplificherà anche l’applicazione per allinearsi con il modo in cui i dati di back-end sono memorizzati nei database e semplifica lo sviluppo. Lo vedremo nei capitoli seguenti.

Notazione delle risorse

Abbiamo parlato delle convenzioni di routing di Rails e dei modelli di URL RESTful. Ora il nostro file routes.rb sarà simile al seguente:

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

In effetti, i percorsi come quello che abbiamo nella sezione posts sono molto comuni, quindi Rails fornisce una notazione speciale resources che aiuta a generarli per te.

Possiamo semplicemente fare:

resources :posts 

Questa linea genererà automaticamente le 8 linee che avevamo prima. Si noti che per l’azione update, Rails consente sia il verbo PUT che PATCH, per motivi di compatibilità.

È possibile eseguire bundle exec rake routes nell’ambiente della riga di comando per verificare che generi esattamente lo stesso insieme di percorsi.

Si noti che questa singola riga genererà 8 percorsi. Nel nostro caso abbiamo bisogno di tutti i percorsi qui, ma se hai solo bisogno di un sottoinsieme dei percorsi, puoi definirli in modo più esplicito come:

resources :posts, only: 

Questa riga sopra genererebbe solo 3 percorsi per te-digita bundle exec rake routes per verificarlo.

Risorse nidificate

Rails ci consente anche di annidare le risorse per creare pattern URL con più risorse, vedi sotto:

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

Esegui bundle exec rake routes e vedi l’output – dovrebbe essere lo stesso di quello che avevamo prima.

Aiutanti percorso

Quando si esegue bundle exec rake routes, notare la colonna Prefix per alcuni di questi percorsi. Questi sono qui per aiutarci a sapere come utilizzare gli aiutanti di percorso forniti da Rails per i nostri percorsi. Possiamo usare questi prefissi seguiti da _path nei nostri controller e viste per creare facilmente percorsi.

Per esempio:

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

Qual è il vantaggio di utilizzare gli helper URL, piuttosto che codificare i percorsi come /posts/123/comments direttamente nel codice? (ad esempio, nell’azione del controller?) Il motivo per cui si desidera utilizzare gli helper del percorso è che se si desidera modificare i modelli URL nella propria app, è molto più semplice utilizzare gli helper URL per restituire un percorso diverso: diamo un’occhiata a un esempio:

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

Quando aggiungiamo la clausola ” as ” a questa rotta, se esegui bundle exec rake routes, vedrai la colonna Prefix con register e puoi usare register_path per ottenere /register il percorso. Ora, se vogliamo cambiare il percorso in /login , tutto ciò che dobbiamo fare è solo:

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

Ora il nostro register_path ci dà /login. Non dobbiamo cambiare il nostro codice nell’app Rails.

Altre convenzioni di routing

Prima di andare avanti, diamo una rapida occhiata a un paio di varianti di ciò che abbiamo già visto, così come alcune altre funzionalità disponibili in 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 

Analizziamo tutte le funzionalità sopra elencate una alla volta.

  • root: root viene utilizzato per specificare quale azione mappa a ” / ” (l’URL di livello superiore del nostro sito che non ha percorso).L’URL principale del tuo sito web / app è il più comunemente usato, a causa di questo root dovrebbe essere specifiedat nella parte superiore del file routes.

  • partita + via: match viene utilizzato per abbinare i modelli di URL a uno o più percorsi. Possiamo anche specificare quale verbo HTTP può essere utilizzato per la corrispondenza a un URL con questo modello. Lo facciamo passando un hash al metodo match. La chiave per questo hash è via e il valore è un array di verbi HTTP. match è una forma più generale di alcuni metodi di routing HTTP più comunemente utilizzati, come get, post e delete. Può richiedere tutte le stesse opzioni di questi metodi, ma, rispetto a questi metodi, offre un po ‘ più di flessibilità.
    Ad esempio, usando match possiamo specificare un URL che corrisponde a due percorsi diversi, ognuno corrispondente a due diversi verbi HTTP. Normalmente, fare questo richiederebbe due comandi, invece di uno. Possiamo vedere questo dal nostro esempio sopra, dove abbiniamo il pattern URL '/authors/:id' all’azione 'authors#update'. Specifichiamo quindi quali verbi HTTP possono essere usati per emettere la richiesta per quell’URL con via: . Specificare sempre un metodo HTTP quando si utilizza match, non farlo può avere implicazioni negative sulla sicurezza dell’applicazione.
    match presenta un’altra opzione per il routing a determinate azioni in Rails. In generale, è meglio attenersi ai metodi più comunemente usati HttpHelpers, come gete post.

  • as: Abbiamo accennato un po ‘ prima che l’opzione as: può essere utilizzata con la nostra dichiarazione di route per cambiare il prefisso per i nostri helper URL. Questo può essere utilizzato in vari modi. Possiamo usare as: per far sì che i nostri aiutanti URL corrispondano meglio agli URL personalizzati. Un altro uso è quello di cambiare l’helper del percorso URL corrente in qualcosa di più intuitivo o qualcosa che corrisponda meglio con le risorse all’interno di un’applicazione.

  • percorso di raccolta: vedi come sopra annidiamo il nostro percorso /popular sotto la risorsa posts. Quindi usiamo on: :collection per specificare quale parte di una risorsa stiamo annidando questa rotta. Abbiamo molti messaggi in modo che è considerato una raccolta. Specificando on: :collectionstiamo dicendo “Abbina un URL con il percorso /posts/popular.”Se non abbiamo aggiunto on: :collection, Rails assumerà che questo percorso corrisponda a un’altra risorsa associata a un singolo membro della nostra raccolta di post. In tal caso il nostro percorso diventerebbe /posts/:id/popular. Possiamo anche specificare più percorsi di raccolta utilizzando un formato di blocco.

collection do get 'popular' end 
  • passaggio di un parametro extra: possiamo specificare un parametro predefinito che viene sempre passato con il nostro hash params quando siamo abbinati a determinati URL. Ci sono due modi per specificare questo; un modo è lo stesso modo in cui facciamo sopra:
get 'popular', on: :collection, action: :index, popular: true 

popular: true verrà passato alla nostra azione con cui il percorso popolare corrisponde tramite l’hash params. Avrà una chiave di :populare un valore di true. Possiamo anche usare una sintassi più esplicita passando un hash al nostro metodo di route get, dovela chiave è defaults: e il valore è un altro hash contenente il nome del parametro che vogliamo passare alla nostra azione.

get 'popular', on: :collection, action: :index, defaults: { popular: true} 
  • percorso membro: possiamo usare on: member per specificare che il nostro percorso corrisponde a un membro di una raccolta. Se usiamo questo il segmento dinamico verrà visualizzato come :id. Verrà creato anche un helper URL come preview_post. Specificando questa rotta con on: member, stiamo dicendo a Rails che questo è un membro di questa particolare risorsa. Che non è solo un’altra risorsa annidata in post, ma più strettamente legata o correlata ai nostri post in questa applicazione. Più percorsi membri possono essere definiti utilizzando un formato di blocco; questo formato utilizza la stessa sintassi del formato di blocco per definire più percorsi di raccolta, basta sostituire collection con member.

  • redirect: C’è un altro concetto di cui parlare che viene visualizzato nel nostro esempio sopra, e questo è il reindirizzamento. Rails ci dà la possibilità di reindirizzare da un percorso all’altro utilizzando un helper di reindirizzamento in combinazione con un percorso.get '/home', to: redirect('/'). Se qualcuno tenta di accedere al percorso /home, verrà immediatamente reindirizzato al percorso principale /. Questo non è limitato a un solo percorso URL, ovviamente; potremmo anche avere qualcosa del genere: get '/home', to: redirect('/travel').

Recensione

I percorsi Rails si trovano nella parte anteriore di un’applicazione. Un percorso interpreta una richiesta HTTP in entrata e:

  • abbina una richiesta a un’azione del controller in base alla combinazione di un verbo HTTP e il pattern URL della richiesta
  • acquisisce i dati nell’URL per essere disponibili inparams nelle azioni del controller
  • Rails incoraggia gli sviluppatori a utilizzare pattern URL RESTful durante la configurazione dei percorsi, con concettualizzazione della manipolazione delle risorse con verbi HTTP.
  • È possibile utilizzare la macro resources per generare percorsi RESTful molto rapidamente.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.