Routes et ressources

Conventions de routage de base

Examinons nos routes telles qu’elles sont maintenant, en utilisant 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 

L’une des informations clés des conventions Rails est que les applications centrées sur les données (ou les applications CRUDy) ont tendance à avoir des moyens très similaires pour permettre aux utilisateurs d’interagir avec l’application, qui sont:

  • une page pour afficher une liste de quelque chose
  • afficher quelque chose
  • afficher un formulaire pour créer une nouvelle instance de quelque chose
  • créer réellement quelque chose
  • afficher un formulaire pour modifier une instance de quelque chose
  • mettre à jour réellement quelque chose
  • supprimer quelque chose

Ces sept « modèles d’interaction » sont si courants que Rails fournit un ensemble solide de conventions allant du routage aux contrôleurs, aux vues et aux formulaires pour simplifier ces flux de travail. Nous allons nous concentrer sur la partie routage maintenant.

Pour le routage, la convention est qu’au lieu de nous devoir trouver les modèles d’URL, Rails nous recommande de structurer les URL et les actions de contrôleur correspondantes de la manière suivante:

Flux de travail VERBE HTTP CHEMIN Action du contrôleur
Afficher une liste de messages GET / messages messages #index
Afficher un article OBTENIR / messages/:id messages # afficher
Afficher la page pour créer un article GET /posts/new posts #new
Créer un message MESSAGE / messages messages # créer
Afficher la page pour modifier un article GET /posts/:id/edit posts #edit
Mettre à jour un article PUT/PATCH /posts/:id posts #update
Supprimer un message SUPPRIMER / messages/:id messages #détruire

Nous pouvons changer la partie post de notre routage actuel pour suivre cette convention:

# 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 

Et dans le fichier 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 

Notez qu’avec ce nouveau modèle, il y a beaucoup moins de verbes dans l’URL elle-même, mais nous nous appuyons sur les verbes HTTP (GET/POST/PUT/PATCH/DELETE) pour fournir la sémantique pour les autres modèles d’URL identiques, par exemple /posts/:id.

Notez que PUT avait été utilisé pour la mise à jour des ressources jusqu’à récemment, lorsque PATCH a été déterminé comme une meilleure correspondance sémantique pour cette action. Depuis lors, Rails a préféré PATCH, mais en autorisant les deux verbes pour les mises à jour.

Un autre changement que nous verrons plus tard est que nous acheminerons toutes les URL liées aux publications vers un PostsController au lieu de tout gérer en ApplicationController. Les noms d’action de PostController

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

sont également des conventions correspondant à l’interaction 7 motifs.

C’est l’ensemble de conventions le plus puissant que Rails vous impose en tant que développeur d’applications. Nous vous demanderons de faire un effort pour le mémoriser. Nous reviendrons sur cela de nombreuses fois tout au long du livre pour vous aider à le faire également.

Routage Pour plusieurs ressources

Souvent, nous avons besoin de plusieurs ressources présentes dans l’URL. Par exemple, pour notre application de blog chaque fois que nous avons besoin d’un itinéraire pour créer un commentaire, il est très important que nous sachions sur quel article ce commentaire est créé.

Nous sommes en train de le faire:

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

La convention Rails d’une URL avec plusieurs ressources associées consiste à commencer par la ressource « contenant » jusqu’à la ressource « la plus interne ». Par exemple, nos itinéraires pour les commentaires changeraient en:

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

La sémantique de ces URL représente: « Créer un commentaire sous un message spécifique » et « supprimer un commentaire sous un message spécifique ». La dernière route, « afficher tous les commentaires dans le système », n’a pas besoin d’être « étendue » sous un message, donc l’URL n’a pas à mener avec « /messages ».

Si nous devons avoir plusieurs ressources dans l’URL avec leurs IDENTIFIANTS, la convention est telle que la dernière ressource utilisera l’espace réservé :id et tout le reste sera :resource_id tel que :post_id.

Restful

REST signifie « Transfert d’État représentatif ». C’est un style d’architecture logicielle et une ligne directrice pour créer des services Web évolutifs. REST, en tant que moyen de structurer les applications Web, a de nombreuses facettes, mais regardons simplement comment cela s’applique à l’interface que nous utilisons pour interagir avec les applications Web, les URL.

Pour voir comment REST simplifie la sémantique des URL, parcourons un exemple. Disons que nous construisons un service de commande de pizzas en ligne. Une implémentation naïve des interfaces du service (URLs) serait:

/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 

Une conception d’interface RESTful ressemblerait à ceci:

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

Vous pouvez voir que les interfaces RESTful sont centrées sur des « noms » ou des « ressources », en supprimant les « verbes » des interfaces mais en s’appuyant sur les verbes HTTP standardisés (GET/POST/PUT/DELETE) pour fournir la sémantique CRUD pour les actions. Verbes tels que check, place, cancel sont mappés directement aux verbes HTTP de GET pour récupérer, POST pour créer et DELETE pour détruire la ressource order. pay et expedite sont structurés comme création (HTTP POST) de sous-ressources de payments et expeditions sous ressource orders.

Interfaces RESTful modèles d’interaction d’applications Web standardisés pour les rendre plus faciles à comprendre et à programmer. Parce que les interfaces sont centrées sur la manipulation des ressources, les réponses sont beaucoup plus prévisibles. Une analogie de la façon dont le modèle d’architecture RESTful simplifie l’interaction avec les services Web serait la façon dont la base de données relationnelle et le langage SQL simplifient le stockage de données. Avant la base de données relationnelle et SQL, les données étaient généralement stockées dans des systèmes propriétaires avec une logique spécifique pour interagir avec eux, ce qui signifiait que sur chaque projet, vous deviez apprendre un ensemble d’instructions différent pour interagir avec les données. Les bases de données relationnelles et SQL ont donné une structure de données commune (enregistrements de données sous forme de lignes et de colonnes stockées dans des tables) et un ensemble d’interfaces communes – quatre verbes simples de SELECT, INSERT, UPDATE et DELETE qui peut prendre en charge tous les types d’applications.

L’adoption d’une interface RESTful pour votre application Web rationalisera également votre application pour l’aligner sur la façon dont les données backend sont stockées dans les bases de données, et facilitera le développement. Nous verrons cela dans les chapitres suivants.

Notation des ressources

Nous avons parlé des conventions de routage de Rails et des modèles d’URL RESTful. Maintenant, notre fichier routes.rb ressemblerait à ce qui suit:

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

En fait, les routes comme ce que nous avons dans la section posts sont très courantes, donc Rails fournit une notation spéciale resources qui aide à les générer pour vous.

Nous pouvons simplement faire:

resources :posts 

Cette ligne générera automatiquement les 8 lignes que nous avions auparavant. Notez que pour l’action update, Rails autorise les verbes PUT et PATCH, pour des raisons de compatibilité.

Vous pouvez exécuter bundle exec rake routes dans votre environnement de ligne de commande pour vérifier qu’il génère exactement le même ensemble de routes.

Notez que cette ligne unique générera 8 routes. Dans notre cas, nous avons besoin de toutes les routes ici, mais si vous n’avez besoin que d’un sous-ensemble des routes, vous pouvez les définir plus explicitement comme:

resources :posts, only: 

Cette ligne ci-dessus ne générerait que 3 itinéraires pour vous – tapez bundle exec rake routes pour le vérifier.

Ressources imbriquées

Rails nous permet également d’imbriquer des ressources pour créer des modèles d’URL avec plusieurs ressources, voir ci-dessous:

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

Exécutez bundle exec rake routes et voyez la sortie – cela devrait être le même que ce que nous avions auparavant.

Assistants de chemin

Lorsque vous exécutez bundle exec rake routes, notez la colonne Prefix pour certaines de ces routes. Ceux-ci sont là pour nous aider à savoir comment utiliser les assistants de chemin fournis par Rails pour nos itinéraires. Nous pouvons utiliser ces préfixes suivis de _path dans nos contrôleurs et vues pour créer facilement des chemins.

Par exemple:

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

Quel est l’avantage d’utiliser des assistants d’URL, plutôt que de coder en dur les chemins tels que /posts/123/comments directement dans votre code? (par exemple, dans l’action de votre contrôleur?) La raison pour laquelle vous souhaitez utiliser des assistants de chemin est que si vous souhaitez modifier les modèles d’URL dans votre application, il est beaucoup plus facile d’utiliser les assistants d’URL pour renvoyer un chemin différent – regardons un exemple:

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

Lorsque nous ajoutons la clause « as » à cette route, si vous exécutez bundle exec rake routes, vous verrez la colonne Prefix avec register, et vous pouvez utiliser register_path pour obtenir /register le chemin. Maintenant, si nous voulons changer le chemin en /login, tout ce que nous avons à faire est simplement de:

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

Maintenant, notre register_path nous donne /login. Nous n’avons pas du tout à changer notre code dans l’application Rails.

Plus de conventions de routage

Avant de passer à autre chose, jetons un coup d’œil à quelques variantes de ce que nous avons déjà vu, ainsi qu’à d’autres fonctionnalités disponibles dans le routage des rails:

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

Décomposons toutes les fonctionnalités énumérées ci-dessus une à la fois.

  • root: root est utilisé pour spécifier quelle action correspond à « / » (l’URL de premier niveau de notre site qui n’a pas de chemin).L’URL racine de votre site Web / application est la plus couramment utilisée, à cause de cela root doit être spécifié en haut du fichier routes.

  • match + via: match est utilisé pour faire correspondre les modèles d’URL à une ou plusieurs routes. Nous pouvons également spécifier quel verbe HTTP peut être utilisé pour faire correspondre une URL avec ce modèle. Nous le faisons en passant un hachage à la méthode match. La clé de ce hachage est via, et la valeur est un tableau de verbes HTTP. match est une forme plus générale de certaines méthodes de routage HTTP plus couramment utilisées, telles que get, post et delete. Cela peut prendre toutes les mêmes options que ces méthodes, mais, par rapport à ces méthodes, cela donne un peu plus de flexibilité.
    Par exemple, en utilisant match, nous pouvons spécifier une URL qui correspond à deux routes différentes, chacune correspondant à deux verbes HTTP différents. Normalement, cela nécessiterait deux commandes, au lieu d’une. Nous pouvons le voir dans notre exemple ci-dessus, où nous associons le modèle d’URL '/authors/:id' à l’action 'authors#update'. Nous spécifions ensuite quels verbes HTTP peuvent être utilisés pour émettre la requête pour cette URL avec via: . Spécifiez toujours une méthode HTTP lorsque vous utilisez match, ne pas le faire peut avoir des implications négatives sur la sécurité de votre application.
    match présente une autre option de routage vers certaines actions dans Rails. En général, il est préférable de s’en tenir aux méthodes HttpHelpers les plus couramment utilisées, telles que get et post.

  • as: Nous avons mentionné un peu plus tôt que l’option as: peut être utilisée avec notre déclaration de route pour changer le préfixe de nos assistants d’URL. Cela peut être utilisé de différentes manières. Nous pouvons utiliser as: pour que nos assistants d’URL correspondent mieux aux URL personnalisées. Une autre utilisation consiste à changer l’assistant de chemin d’URL actuel en quelque chose de plus intuitif ou qui correspond mieux aux ressources d’une application.

  • itinéraire de collecte : Voyez comment nous imbriquons notre itinéraire /popular sous la ressource posts. Nous utilisons ensuite on: :collection pour spécifier la partie d’une ressource sous laquelle nous imbriquons cette route. Nous avons beaucoup de messages, ce qui est considéré comme une collection. En spécifiant on: :collection, nous disons: « Faites correspondre une URL avec le chemin /posts/popular. »Si nous n’ajoutons pas on: :collection, Rails supposera que cette route correspond à une autre ressource associée à un seul membre de notre collection de messages. Dans ce cas, notre itinéraire deviendrait /posts/:id/popular. Nous pouvons également spécifier plusieurs routes de collecte en utilisant un format de bloc.

collection do get 'popular' end 
  • passer un paramètre supplémentaire: Nous pouvons spécifier un paramètre par défaut qui est toujours transmis avec notre hachage params lorsque nous sommes mis en correspondance avec certaines URL. Il y a deux façons de spécifier cela; une façon est la même que nous le faisons ci-dessus:
get 'popular', on: :collection, action: :index, popular: true 

popular: true sera transmis à notre action avec laquelle la route populaire correspond via le hachage params. Il aura une clé de :popular et une valeur de true. Nous pouvons également utiliser une syntaxe plus explicite en passant un hachage à notre méthode de route get, où la clé est defaults: et la valeur est un autre hachage contenant le nom du paramètre que nous voulons transmettre à notre action.

get 'popular', on: :collection, action: :index, defaults: { popular: true} 
  • route membre : Nous pouvons utiliser on: member pour spécifier que notre route correspond à un membre d’une collection. Si nous l’utilisons, le segment dynamique apparaîtra sous la forme :id. Un assistant d’URL sera également créé en tant que preview_post. En spécifiant cette route avec on: member, nous indiquons à Rails qu’il s’agit d’un membre de cette ressource particulière. Qu’il ne s’agit pas simplement d’une autre ressource imbriquée sous les publications, mais plus étroitement liée ou liée à nos publications dans cette application. Plusieurs routes membres peuvent être définies à l’aide d’un format de bloc ; ce format utilise la même syntaxe que le format de bloc pour définir plusieurs routes de collection, il suffit de remplacer collection par member.

  • redirection: Il y a un autre concept dont il faut parler qui est affiché dans notre exemple ci-dessus, et c’est la redirection. Rails nous donne la possibilité de rediriger d’un chemin vers un autre en utilisant un assistant de redirection en conjonction avec une route.get '/home', to: redirect('/'). Si quelqu’un tente d’accéder au chemin /home, il sera immédiatement redirigé vers le chemin racine /. Ce n’est pas limité à un seul chemin d’URL bien sûr; nous pourrions aussi avoir quelque chose comme ceci: get '/home', to: redirect('/travel').

Examen

Les itinéraires de rails se trouvent à l’avant d’une application. Une route interprète une requête HTTP entrante et:

  • fait correspondre une requête à une action de contrôleur sur la base de la combinaison d’un verbe HTTP et du modèle d’URL de requête
  • capture des données dans l’URL pour qu’elles soient disponibles dans params dans les actions de contrôleur
  • Rails encourage les développeurs à utiliser des modèles d’URL RESTful lors de la configuration des routes, avec une conceptualisation de la manipulation des ressources avec des verbes HTTP.
  • Vous pouvez utiliser la macro resources pour générer très rapidement des routes RESTful.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.