Recherche…


Introduction

Le routeur Rails reconnaît les URL et les distribue à l'action d'un contrôleur. Il peut également générer des chemins et des URL, évitant d'avoir à coder en dur des chaînes dans vos vues.

Remarques

"Routage" est en général la manière dont les URL sont "gérées" par votre application. Dans le cas de Rails, c'est généralement quel contrôleur et quelle action de ce contrôleur traitera une URL entrante particulière. Dans les applications Rails, les routes sont généralement placées dans le fichier config/routes.rb .

Routage des ressources (de base)

Les routes sont définies dans config/routes.rb . Ils sont souvent définis comme un groupe d'itinéraires connexes, en utilisant les resources ou resource méthodes de resource .

resources :users créent les sept itinéraires suivants, tous UsersController aux actions de UsersController :

get       '/users',          to: 'users#index'
post      '/users',          to: 'users#create'
get       '/users/new',      to: 'users#new'
get       '/users/:id/edit', to: 'users#edit'
get       '/users/:id',      to: 'users#show'
patch/put '/users/:id',      to: 'users#update'
delete    '/users/:id',      to: 'users#destroy'

Les noms des actions sont affichés après le # dans le paramètre to ci-dessus. Les méthodes avec ces mêmes noms doivent être définies dans app/controllers/users_controller.rb comme suit:

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

Vous pouvez limiter les actions générées avec only ou except :

resources :users, only:   [:show]
resources :users, except: [:show, :index]

Vous pouvez afficher tous les itinéraires de votre application à tout moment en exécutant:

5.0
$ rake routes
5.0
$ rake routes
# OR
$ rails routes
users     GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
new_user  GET    /users/new(.:format)      users#new
edit_user GET    /users/:id/edit(.:format) users#edit
user      GET    /users/:id(.:format)      users#show
          PATCH  /users/:id(.:format)      users#update
          PUT    /users/:id(.:format)      users#update
          DELETE /users/:id(.:format)      users#destroy

Pour afficher uniquement les itinéraires mappés sur un contrôleur particulier:

5.0
$ rake routes -c static_pages
static_pages_home    GET    /static_pages/home(.:format)    static_pages#home
static_pages_help    GET    /static_pages/help(.:format)    static_pages#help
5.0
$ rake routes -c static_pages
static_pages_home    GET    /static_pages/home(.:format)    static_pages#home
static_pages_help    GET    /static_pages/help(.:format)    static_pages#help

# OR

$ rails routes -c static_pages
static_pages_home    GET    /static_pages/home(.:format)    static_pages#home
static_pages_help    GET    /static_pages/help(.:format)    static_pages#help

Vous pouvez rechercher dans les itinéraires en utilisant l'option -g . Cela montre toute route qui correspond partiellement au nom de la méthode d'assistance, au chemin de l'URL ou au verbe HTTP:

5.0
$ rake routes -g new_user     # Matches helper method
$ rake routes -g POST         # Matches HTTP Verb POST 
5.0
$ rake routes -g new_user     # Matches helper method
$ rake routes -g POST         # Matches HTTP Verb POST 
# OR
$ rails routes -g new_user    # Matches helper method
$ rails routes -g POST        # Matches HTTP Verb POST 

De plus, lorsque vous exécutez le serveur rails en mode développement, vous pouvez accéder à une page Web qui affiche tous vos itinéraires avec un filtre de recherche, priorisé de haut en bas, à <hostname>/rails/info/routes . Il ressemblera à ceci:

Assistant Verbe HTTP Chemin Action du contrôleur
Chemin / URL [Path Match]
chemin_utilisateur OBTENIR /users(.:format) utilisateurs # index
POSTER /users(.:format) les utilisateurs # créent
new_user_path OBTENIR /users/new(.:format) utilisateurs # new
edit_user_path OBTENIR /users/:id/edit(.:format) utilisateurs # modifier
chemin_utilisateur OBTENIR /users/:id(.:format) utilisateurs # montrent
PIÈCE /users/:id(.:format) utilisateurs # mise à jour
METTRE /users/:id(.:format) utilisateurs # mise à jour
EFFACER /users/:id(.:format) les utilisateurs # détruisent

Les routes peuvent être déclarées disponibles uniquement pour les membres (pas les collections) à l'aide de la resource méthode au lieu de resources dans routes.rb . Avec la resource , une route d' index n'est pas créée par défaut, mais uniquement lorsque vous en demandez explicitement une comme ceci:

resource :orders, only: [:index, :create, :show]

Contraintes

Vous pouvez filtrer les routes disponibles à l'aide de contraintes.

Il existe plusieurs manières d’utiliser des contraintes, notamment:

Par exemple, une contrainte basée sur la demande pour autoriser uniquement une adresse IP spécifique à accéder à une route:

constraints(ip: /127\.0\.0\.1$/) do
  get 'route', to: "controller#action"
end

Voir d'autres exemples similaires ActionDispatch :: Routing :: Mapper :: Scoping .

Si vous voulez faire quelque chose de plus complexe, vous pouvez utiliser des contraintes plus avancées et créer une classe pour envelopper la logique:

# lib/api_version_constraint.rb
class ApiVersionConstraint
  def initialize(version:, default:)
    @version = version
    @default = default
  end

  def version_header
    "application/vnd.my-app.v#{@version}"
  end

  def matches?(request)
    @default || request.headers["Accept"].include?(version_header)
  end
end

# config/routes.rb
require "api_version_constraint"

Rails.application.routes.draw do
  namespace :v1, constraints: ApiVersionConstraint.new(version: 1, default: true) do
    resources :users # Will route to app/controllers/v1/users_controller.rb
  end

  namespace :v2, constraints: ApiVersionConstraint.new(version: 2) do
    resources :users # Will route to app/controllers/v2/users_controller.rb
  end
end

Un formulaire, plusieurs boutons de soumission

Vous pouvez également utiliser la valeur des balises submit d'un formulaire comme contrainte pour acheminer une action différente. Si vous avez un formulaire avec plusieurs boutons d'envoi (par exemple "preview" et "submit"), vous pouvez capturer cette contrainte directement dans vos routes.rb , au lieu d'écrire du javascript pour changer l'URL de destination du formulaire. Par exemple, avec le gem commit_param_routing, vous pouvez tirer parti de rails submit_tag

Rails submit_tag premier paramètre submit_tag vous permet de modifier la valeur de votre paramètre de validation de formulaire

# app/views/orders/mass_order.html.erb
<%= form_for(@orders, url: mass_create_order_path do |f| %>
    <!-- Big form here -->
  <%= submit_tag "Preview" %>
  <%= submit_tag "Submit" %>
  # => <input name="commit" type="submit" value="Preview" />
  # => <input name="commit" type="submit" value="Submit" />
  ...
<% end %>

# config/routes.rb
resources :orders do
  # Both routes below describe the same POST URL, but route to different actions 
  post 'mass_order', on: :collection, as: 'mass_order',
    constraints: CommitParamRouting.new('Submit'), action: 'mass_create' # when the user presses "submit"
  post 'mass_order', on: :collection,
    constraints: CommitParamRouting.new('Preview'), action: 'mass_create_preview' # when the user presses "preview"
  # Note the `as:` is defined only once, since the path helper is mass_create_order_path for the form url
  # CommitParamRouting is just a class like ApiVersionContraint
end

Itinéraires de portée

Rails propose plusieurs méthodes pour organiser vos itinéraires.

Portée par URL :

scope 'admin' do
  get 'dashboard', to: 'administration#dashboard'
  resources 'employees'
end

Cela génère les routes suivantes

get       '/admin/dashboard',          to: 'administration#dashboard'
post      '/admin/employees',          to: 'employees#create'
get       '/admin/employees/new',      to: 'employees#new'
get       '/admin/employees/:id/edit', to: 'employees#edit'
get       '/admin/employees/:id',      to: 'employees#show'
patch/put '/admin/employees/:id',      to: 'employees#update'
delete    '/admin/employees/:id',      to: 'employees#destroy'

Du côté du serveur, il peut être plus judicieux de conserver certaines vues dans un sous-dossier différent, afin de séparer les vues d’administration des vues des utilisateurs.

Portée par module

scope module: :admin do
  get 'dashboard', to: 'administration#dashboard'
end

module recherche les fichiers du contrôleur sous le sous-dossier du nom donné

get       '/dashboard',          to: 'admin/administration#dashboard'

Vous pouvez renommer le préfixe des aides de chemin en ajoutant un paramètre as

scope 'admin', as: :administration do
  get 'dashboard'
end

# => administration_dashboard_path

Rails fournit un moyen pratique de faire tout ce qui précède, en utilisant la méthode d' namespace . Les déclarations suivantes sont équivalentes

namespace :admin do
end

scope 'admin', module: :admin, as: :admin

Portée par contrôleur

scope controller: :management do
  get 'dashboard'
  get 'performance'
end

Cela génère ces routes

get       '/dashboard',          to: 'management#dashboard'
get       '/performance',        to: 'management#performance'

Nidification peu profonde

Les itinéraires de ressources acceptent une option :shallow qui permet de raccourcir les URL lorsque cela est possible. Les ressources ne doivent pas être imbriquées à plus d'un niveau. Une façon d'éviter cela est de créer des routes peu profondes. L'objectif est de laisser de côté les segments d'URL de la collection parent où ils ne sont pas nécessaires. Le résultat final est que les seules routes imbriquées générées sont pour :index :create et :new actions. Les autres sont conservés dans leur propre contexte d'URL peu profond. Il existe deux options pour la portée des itinéraires peu profonds personnalisés:

  • : shallow_path : préfixes des chemins de membre avec un paramètre spécifié

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : shallow_prefix : ajoute les paramètres spécifiés aux helpers nommés

    scope shallow_prefix: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    

Nous pouvons également illustrer des routes shallow en:

resources :auctions, shallow: true do
  resources :bids do
   resources :comments
  end
end 

alternativement codé comme suit (si vous êtes bloqué):

resources :auctions do
 shallow do
   resources :bids do
     resources :comments
   end
 end
end

Les itinéraires résultants sont:

Préfixe Verbe Modèle d'URI
bid_comments OBTENIR /bids/:bid_id/comments(.:format)
POSTER /bids/:bid_id/comments(.:format)
new_bid_comment OBTENIR /bids/:bid_id/comments/new(.:format)
edit_comment OBTENIR /comments/:id/edit(.:format)
commentaire OBTENIR /comments/:id(.:format)
PIÈCE /comments/:id(.:format)
METTRE /comments/:id(.:format)
EFFACER /comments/:id(.:format)
auction_bids OBTENIR /auctions/:auction_id/bids(.:format)
POSTER /auctions/:auction_id/bids(.:format)
new_auction_bid OBTENIR /auctions/:auction_id/bids/new(.:format)
edit_bid OBTENIR /bids/:id/edit(.:format)
offre OBTENIR /bids/:id(.:format)
PIÈCE /bids/:id(.:format)
METTRE /bids/:id(.:format)
EFFACER /bids/:id(.:format)
les enchères OBTENIR /auctions(.:format)
POSTER /auctions(.:format)
new_auction OBTENIR /auctions/new(.:format)
edit_auction OBTENIR /auctions/:id/edit(.:format)
enchères OBTENIR /auctions/:id(.:format)
PIÈCE /auctions/:id(.:format)
METTRE /auctions/:id(.:format)
EFFACER /auctions/:id(.:format)

Si vous analysez les routes générées avec soin, vous remarquerez que les parties imbriquées de l'URL ne sont incluses que lorsqu'elles sont nécessaires pour déterminer les données à afficher.

Les soucis

Pour éviter la répétition dans les routes imbriquées, les préoccupations offrent un excellent moyen de partager des ressources communes réutilisables. Pour créer un problème, utilisez la méthode concern dans le fichier routes.rb . La méthode attend un symbole et un bloc:

concern :commentable do
  resources :comments
end

Tout en ne créant aucune route elle-même, ce code permet d'utiliser l'attribut :concerns sur une ressource. L'exemple le plus simple serait:

resource :page, concerns: :commentable

La ressource imbriquée équivalente ressemblerait à ceci:

resource :page do
  resource :comments
end

Cela permettrait, par exemple, de créer les itinéraires suivants:

/pages/#{page_id}/comments
/pages/#{page_id}/comments/#{comment_id}

Pour que les préoccupations soient significatives, il doit y avoir plusieurs ressources qui utilisent le problème. Des ressources supplémentaires peuvent utiliser l'une des syntaxes suivantes pour appeler le problème:

resource :post, concerns: %i(commentable)
resource :blog do
  concerns :commentable
end

Redirection

Vous pouvez effectuer la redirection dans les itinéraires Rails comme suit:

4.0
get '/stories', to: redirect('/posts')
4.0
match "/abc" => redirect("http://example.com/abc")

Vous pouvez également rediriger tous les itinéraires inconnus vers un chemin donné:

4.0
match '*path' => redirect('/'), via: :get
# or
get '*path' => redirect('/')
4.0
match '*path' => redirect('/')

Itinéraires de membre et de collection

La définition d'un bloc membre dans une ressource crée un itinéraire pouvant agir sur un membre individuel de cet itinéraire basé sur une ressource:

resources :posts do
  member do
    get 'preview'
  end
end

Cela génère l'itinéraire de membre suivant:

get '/posts/:id/preview', to: 'posts#preview'
# preview_post_path

Les itinéraires de collecte permettent de créer des itinéraires pouvant agir sur une collection d'objets ressource:

resources :posts do
  collection do
    get 'search'
  end
end

Cela génère l'itinéraire de collecte suivant:

get '/posts/search', to: 'posts#search'
# search_posts_path

Une syntaxe alternative:

resources :posts do
  get 'preview', on: :member
  get 'search',  on: :collection
end

Paramètres d'URL avec un point

Si vous souhaitez prendre en charge un paramètre d'URL plus complexe qu'un numéro d'identification, vous pouvez rencontrer des problèmes avec l'analyseur si la valeur contient un point. Tout ce qui suit une période sera considéré comme un format (c.-à-d. Json, xml).

Vous pouvez contourner cette limitation en utilisant une contrainte pour élargir l'entrée acceptée.

Par exemple, si vous souhaitez référencer un enregistrement d'utilisateur par adresse électronique dans l'URL:

resources :users, constraints: { id: /.*/ }

Route racine

Vous pouvez ajouter un itinéraire de page d'accueil à votre application avec la méthode root .

# config/routes.rb
Rails.application.routes.draw do
  root "application#index"
  # equivalent to:
  # get "/", "application#index"  
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  def index
    render "homepage"
  end
end

Et dans les terminaux, les rake routes ( rake routes rails routes dans Rails 5) produiront:

root     GET    /         application#index

Étant donné que la page d'accueil est généralement l'itinéraire le plus important et que les itinéraires sont classés par ordre de priorité dans l'ordre dans lequel ils apparaissent, l'itinéraire root doit généralement être le premier de votre fichier de routes.

Actions RESTful supplémentaires

resources :photos do
  member do
    get 'preview'
  end
  collection do
    get 'dashboard'
  end
end

Cela crée les routes suivantes en plus des 7 routes RESTful par défaut :

get       '/photos/:id/preview',          to: 'photos#preview'
get       '/photos/dashboards',           to: 'photos#dashboard'

Si vous voulez faire cela pour des lignes simples, vous pouvez utiliser:

resources :photos do
  get 'preview',   on: :member
  get 'dashboard', on: :collection
end

Vous pouvez également ajouter une action au chemin /new :

resources :photos do
  get 'preview', on: :new
end

Qui va créer:

get       '/photos/new/preview',          to: 'photos#preview'

Soyez attentif lorsque vous ajoutez des actions à vos routes RESTful, vous manquez probablement une autre ressource!

Portée disponible locale

Si votre application est disponible dans différentes langues, vous affichez généralement les paramètres régionaux actuels dans l'URL.

scope '/(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
    root 'example#root'
    # other routes
end

Votre racine sera accessible via les paramètres régionaux définis dans I18n.available_locales .

Monter une autre application

le montage est utilisé pour monter une autre application (essentiellement une application en rack) ou des moteurs de rails à utiliser dans l'application en cours

syntaxe:

mount SomeRackApp, at: "some_route"

Vous pouvez maintenant accéder aux applications montées ci-dessus en utilisant l'assistant de route some_rack_app_path ou some_rack_app_url .

Mais si vous voulez renommer ce nom d’assistant, vous pouvez le faire en tant que:

mount SomeRackApp, at: "some_route", as: :myapp

Cela générera les myapp_path et myapp_url qui peuvent être utilisés pour naviguer dans cette application montée.

Itinéraires de redirections et de caractères génériques

Si vous souhaitez fournir une URL hors de la convenance pour votre utilisateur, mais la mapper directement à une autre que vous utilisez déjà. Utilisez une redirection:

# config/routes.rb
TestApp::Application.routes.draw do
  get 'courses/:course_name' => redirect('/courses/%{course_name}/lessons'), :as => "course"
end

Eh bien, ça a été intéressant rapidement. Le principe de base consiste à utiliser la méthode #redirect pour envoyer une route à une autre. Si votre itinéraire est assez simple, c'est une méthode très simple. Mais si vous voulez aussi envoyer les paramètres d'origine, vous devez faire un peu de gymnastique en capturant le paramètre dans %{here} . Notez les guillemets simples autour de tout.

Dans l'exemple ci-dessus, nous avons également renommé la route pour plus de commodité en utilisant un alias avec le paramètre: as. Cela nous permet d'utiliser ce nom dans des méthodes telles que les aides #_path. Encore une fois, testez vos $ rake routes avec des questions.

Diviser les itinéraires en plusieurs fichiers

Si votre fichier de routes est extrêmement volumineux, vous pouvez placer vos itinéraires dans plusieurs fichiers et inclure chacun des fichiers avec la méthode require_relative de Ruby:

config/routes.rb :
YourAppName::Application.routes.draw do
  require_relative 'routes/admin_routes'
  require_relative 'routes/sidekiq_routes'
  require_relative 'routes/api_routes'
  require_relative 'routes/your_app_routes'
end
config/routes/api_routes.rb :
YourAppName::Application.routes.draw do
  namespace :api do
    # ...
  end
end

Routes imbriquées

Si vous souhaitez ajouter des routes imbriquées, vous pouvez écrire le code suivant dans le fichier routes.rb .

resources :admins do
  resources :employees
end

Cela générera les itinéraires suivants:

     admin_employees GET      /admins/:admin_id/employees(.:format)            employees#index
                     POST     /admins/:admin_id/employees(.:format)            employees#create
  new_admin_employee GET      /admins/:admin_id/employees/new(.:format)        employees#new
 edit_admin_employee GET      /admins/:admin_id/employees/:id/edit(.:format)   employees#edit
      admin_employee GET      /admins/:admin_id/employees/:id(.:format)        employees#show
                     PATCH    /admins/:admin_id/employees/:id(.:format)        employees#update
                     PUT      /admins/:admin_id/employees/:id(.:format)        employees#update
                     DELETE   /admins/:admin_id/employees/:id(.:format)        employees#destroy
              admins GET      /admins(.:format)                                admins#index
                     POST     /admins(.:format)                                admins#create
           new_admin GET      /admins/new(.:format)                            admins#new
          edit_admin GET      /admins/:id/edit(.:format)                       admins#edit
               admin GET      /admins/:id(.:format)                            admins#show
                     PATCH    /admins/:id(.:format)                            admins#update
                     PUT      /admins/:id(.:format)                            admins#update
                     DELETE   /admins/:id(.:format)                            admins#destroy


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow