Ricerca…


introduzione

Il router Rails riconosce gli URL e li invia all'azione di un controllore. Può anche generare percorsi e URL, evitando la necessità di hardcode stringhe nelle viste.

Osservazioni

"Routing" in generale è il modo in cui gli URL sono "gestiti" dalla tua app. In caso di Rails è in genere il controller e l'azione di quel controller gestirà un particolare URL in arrivo. Nelle app Rails, le rotte vengono di solito collocate nel file config/routes.rb .

Routing delle risorse (base)

Le rotte sono definite in config/routes.rb . Sono spesso definiti come un gruppo di percorsi correlati, utilizzando le resources o i metodi di resource .

resources :users creano i seguenti sette percorsi, tutti UsersController alle azioni di 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'

I nomi delle azioni sono visualizzati dopo il # nel parametro to sopra. I metodi con gli stessi nomi devono essere definiti in app/controllers/users_controller.rb come segue:

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

È possibile limitare le azioni generate only con o except :

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

Puoi visualizzare tutti i percorsi della tua applicazione in qualsiasi momento eseguendo:

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

Per vedere solo le rotte che si associano a un controller particolare:

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

Puoi cercare attraverso i percorsi usando l'opzione -g . Mostra tutte le route che corrispondono parzialmente al nome del metodo helper, al percorso URL o al verbo 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 

Inoltre, quando si esegue il server di rails in modalità di sviluppo, è possibile accedere a una pagina Web che mostra tutti i percorsi con un filtro di ricerca, abbinato in priorità da cima a fondo, in <hostname>/rails/info/routes . Sembrerà così:

aiutante Verbale HTTP Sentiero Controller # Azione
Percorso / Url [Path Match]
users_path OTTENERE /users(.:format) Indice utenti #
INVIARE /users(.:format) utenti creano #
new_user_path OTTENERE /users/new(.:format) utenti # nuova
edit_user_path OTTENERE /users/:id/edit(.:format) gli utenti # modifica
user_path OTTENERE /users/:id(.:format) gli utenti # show
PATCH /users/:id(.:format) gli utenti # aggiornamento
METTERE /users/:id(.:format) gli utenti # aggiornamento
ELIMINA /users/:id(.:format) utenti # distruggono

Le route possono essere dichiarate disponibili solo per i membri (non per le raccolte) utilizzando la resource metodo anziché le resources in routes.rb . Con la resource , una route index non viene creata per impostazione predefinita, ma solo quando ne viene richiesta esplicitamente una come questa:

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

vincoli

Puoi filtrare quali percorsi sono disponibili usando i vincoli.

Esistono diversi modi per utilizzare i vincoli, tra cui:

Ad esempio, un vincolo basato su richiesta per consentire solo a un indirizzo IP specifico di accedere a una rotta:

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

Vedi altri esempi simili ActionDispatch :: Routing :: Mapper :: Scoping .

Se vuoi fare qualcosa di più complesso puoi usare vincoli più avanzati e creare una classe per avvolgere la logica:

# 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 modulo, diversi pulsanti di invio

È inoltre possibile utilizzare il valore dei tag di invio di un modulo come vincolo per eseguire il routing a un'azione diversa. Se hai un modulo con più pulsanti di invio (ad esempio "anteprima" e "invia"), puoi catturare questo vincolo direttamente nel tuo routes.rb , invece di scrivere javascript per modificare l'URL di destinazione del modulo. Ad esempio con la gem di commit_param_routing puoi sfruttare i binari submit_tag

submit_tag parametro submit_tag Rails consente di modificare il valore del parametro di commit della submit_tag

# 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

Percorsi di ricerca

Rails offre diversi modi per organizzare i tuoi percorsi.

Ambito per URL :

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

Questo genera i seguenti percorsi

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'

Potrebbe avere più senso, sul lato server, mantenere alcune viste in una sottocartella diversa, per separare le viste di amministrazione dalle viste degli utenti.

Ambito per modulo

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

module cerca i file del controller sotto la sottocartella del nome specificato

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

È possibile rinominare il prefisso degli helper del percorso aggiungendo un parametro as

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

# => administration_dashboard_path

Rails fornisce un modo conveniente per fare tutto quanto sopra, usando il metodo namespace . Le seguenti dichiarazioni sono equivalenti

namespace :admin do
end

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

Ambito dal controller

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

Questo genera queste rotte

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

Nidificazione superficiale

Le rotte delle risorse accettano una :shallow opzione :shallow che aiuta ad accorciare gli URL laddove possibile. Le risorse non devono essere nidificate a più di un livello. Un modo per evitare questo è creare percorsi poco profondi. L'obiettivo è quello di lasciare i segmenti URL della raccolta principale dove non sono necessari. Il risultato finale è che le sole rotte nidificate generate sono per :index :create e :new azioni. Il resto è tenuto nel proprio contesto URL poco profondo. Ci sono due opzioni per l'ambito di percorsi superficiali personalizzati:

  • : shallow_path : prefissa i percorsi dei membri con un parametro specificato

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : shallow_prefix : aggiunge i parametri specificati agli helper specificati

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

Possiamo anche illustrare i percorsi shallow più:

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

in alternativa codificato come segue (se sei felice del blocco):

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

I percorsi risultanti sono:

Prefisso Verbo Pattern URI
bid_comments OTTENERE /bids/:bid_id/comments(.:format)
INVIARE /bids/:bid_id/comments(.:format)
new_bid_comment OTTENERE /bids/:bid_id/comments/new(.:format)
edit_comment OTTENERE /comments/:id/edit(.:format)
commento OTTENERE /comments/:id(.:format)
PATCH /comments/:id(.:format)
METTERE /comments/:id(.:format)
ELIMINA /comments/:id(.:format)
auction_bids OTTENERE /auctions/:auction_id/bids(.:format)
INVIARE /auctions/:auction_id/bids(.:format)
new_auction_bid OTTENERE /auctions/:auction_id/bids/new(.:format)
edit_bid OTTENERE /bids/:id/edit(.:format)
offerta OTTENERE /bids/:id(.:format)
PATCH /bids/:id(.:format)
METTERE /bids/:id(.:format)
ELIMINA /bids/:id(.:format)
aste OTTENERE /auctions(.:format)
INVIARE /auctions(.:format)
new_auction OTTENERE /auctions/new(.:format)
edit_auction OTTENERE /auctions/:id/edit(.:format)
vendita all'asta OTTENERE /auctions/:id(.:format)
PATCH /auctions/:id(.:format)
METTERE /auctions/:id(.:format)
ELIMINA /auctions/:id(.:format)

Se analizzi attentamente le rotte generate, noterai che le parti annidate dell'URL sono incluse solo quando sono necessarie per determinare quali dati visualizzare.

preoccupazioni

Per evitare la ripetizione in percorsi nidificati, le preoccupazioni forniscono un ottimo modo per condividere risorse comuni che sono riutilizzabili. Per creare un problema, utilizzare la concern del metodo all'interno del file routes.rb . Il metodo si aspetta un simbolo e un blocco:

concern :commentable do
  resources :comments
end

Pur non creando alcuna route, questo codice consente di utilizzare l'attributo :concerns su una risorsa. L'esempio più semplice sarebbe:

resource :page, concerns: :commentable

La risorsa nidificata equivalente sarebbe simile a questa:

resource :page do
  resource :comments
end

Ciò creerebbe, ad esempio, i seguenti percorsi:

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

Affinché le preoccupazioni siano significative, devono esserci più risorse che utilizzano la preoccupazione. Risorse aggiuntive potrebbero utilizzare una qualsiasi delle seguenti sintassi per chiamare la preoccupazione:

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

reindirizzamento

È possibile eseguire il reindirizzamento nei percorsi di Rails come segue:

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

Puoi anche reindirizzare tutte le rotte sconosciute ad un determinato percorso:

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

Percorsi membro e raccolta

La definizione di un blocco membro all'interno di una risorsa crea una route che può agire su un singolo membro di quella rotta basata su risorse:

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

Questo genera il seguente percorso membro:

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

I percorsi di raccolta consentono di creare percorsi che possono agire su una raccolta di oggetti risorsa:

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

Questo genera il seguente percorso di raccolta:

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

Una sintassi alternativa:

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

Param di URL con un punto

Se si desidera supportare un parametro url più complesso di un numero id, è possibile che si verifichi un problema con il parser se il valore contiene un punto. Si presuppone che qualsiasi cosa che segue un periodo sia un formato (es. Json, xml).

È possibile aggirare questa limitazione utilizzando un vincolo per ampliare l'input accettato.

Ad esempio, se desideri fare riferimento a un record utente tramite indirizzo email nell'URL:

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

Root route

Puoi aggiungere un percorso della home page alla tua app con il metodo 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

E in terminal, i rake routes ( rails routes di rails in Rails 5) produrranno:

root     GET    /         application#index

Poiché la home page è in genere il percorso più importante e le route sono prioritarie nell'ordine in cui vengono visualizzate, la route root dovrebbe essere in genere la prima nel file dei percorsi.

Ulteriori azioni RESTful

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

Questo crea i seguenti percorsi oltre alle 7 rotte RESTful predefinite :

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

Se vuoi farlo per linee singole, puoi usare:

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

Puoi anche aggiungere un'azione al /new percorso:

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

Che creerà:

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

Sii consapevole quando aggiungi azioni ai tuoi percorsi RESTful, probabilmente ti manca un'altra risorsa!

Scope disponibili locales

Se la tua applicazione è disponibile in diverse lingue, di solito mostri la locale corrente nell'URL.

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

La tua radice sarà accessibile tramite le impostazioni locali definite in I18n.available_locales .

Montare un'altra applicazione

mount viene utilizzato per montare un'altra applicazione (fondamentalmente un'applicazione rack) o motori di rotaia da utilizzare all'interno dell'applicazione corrente

sintassi:

mount SomeRackApp, at: "some_route"

Ora puoi accedere all'applicazione montata sopra utilizzando helper some_rack_app_path o some_rack_app_url .

Ma se vuoi rinominare questo nome helper puoi farlo come:

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

Questo genererà gli myapp_path e myapp_url che possono essere utilizzati per navigare in questa app montata.

Reindirizzamenti e percorsi Wildcard

Se desideri fornire un URL per comodità all'utente, ma mappalo direttamente a un altro che stai già utilizzando. Utilizza un reindirizzamento:

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

Bene, è diventato interessante velocemente. Il principio di base qui è utilizzare semplicemente il metodo #redirect per inviare una rotta a un'altra rotta. Se il tuo percorso è abbastanza semplice, è un metodo davvero semplice. Ma se vuoi anche inviare i parametri originali, devi fare un po 'di ginnastica catturando il parametro all'interno di %{here} . Nota le singole virgolette attorno a tutto.

Nell'esempio sopra, abbiamo anche rinominato la rotta per comodità usando un alias con: come parametro. Questo ci permette di usare quel nome in metodi come gli helper #_path. Di nuovo, prova le tue $ rake routes con domande.

Suddividi i percorsi in più file

Se il tuo file di rotte è enormemente grande, puoi inserire i tuoi percorsi in più file e includere ognuno dei file con il metodo require_relative di 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

Percorsi nidificati

Se si desidera aggiungere rotte nidificate, è possibile scrivere il seguente codice nel file routes.rb .

resources :admins do
  resources :employees
end

Questo genererà i seguenti percorsi:

     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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow