Sök…


Introduktion

Rails-routern känner igen URL: er och skickar dem till en kontrollers handling. Det kan också generera sökvägar och webbadresser och undvika behovet av att hårddisksträngar i dina vyer.

Anmärkningar

"Routing" i allmänhet är hur URL: er "hanteras" av din app. I Rails-fall är det vanligtvis vilken kontroller och vilken åtgärd för den kontrollen som hanterar en viss inkommande URL. I Rails-appar placeras rutter vanligtvis i filen config/routes.rb .

Resursruting (grundläggande)

Rutter definieras i config/routes.rb . De definieras ofta som en grupp relaterade rutter med hjälp av resources eller resource .

resources :users skapar följande sju rutter, alla mappar till handlingar från 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'

Åtgärdens namn visas efter # i to parametern ovan. Metoder med samma namn måste definieras i app/controllers/users_controller.rb enligt följande:

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

Du kan begränsa de åtgärder som genereras med only eller except :

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

Du kan visa alla rutter för din ansökan när som helst genom att köra:

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

Så här ser du bara de rutter som kartlägger till en viss controller:

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

Du kan söka igenom rutter med alternativet -g . Detta visar alla rutter som delvis matchar hjälpmedelsnamnet, URL-banan eller HTTP-verbet:

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 

När du kör rails i utvecklingsläge kan du dessutom komma åt en webbsida som visar alla dina rutter med ett sökfilter, matchat i prioritet från topp till botten, på <hostname>/rails/info/routes . Det kommer att se ut så här:

Hjälpare HTTP Verb Väg Controller # Action
Sökväg / URL [Path Match]
users_path SKAFFA SIG /users(.:format) användare # index
POSTA /users(.:format) användarnas # skapar
new_user_path SKAFFA SIG /users/new(.:format) användare # nya
edit_user_path SKAFFA SIG /users/:id/edit(.:format) användare # redigera
user_path SKAFFA SIG /users/:id(.:format) användare # show
LAPPA /users/:id(.:format) användare # update
SÄTTA /users/:id(.:format) användare # update
RADERA /users/:id(.:format) användarnas # förstör

Rutter kan förklaras tillgängliga för endast medlemmar (inte samlingar) med resource istället för resources i routes.rb . Med resource , en index är rutten inte skapas som standard, men bara när det uttryckligen ber om en så här:

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

begränsningar

Du kan filtrera vilka rutter som är tillgängliga med begränsningar.

Det finns flera sätt att använda begränsningar inklusive:

Till exempel en begärd baserad begränsning som endast tillåter en specifik IP-adress att komma åt en rutt:

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

Se andra liknande exempel ActionDispatch :: Routing :: Mapper :: Scoping .

Om du vill göra något mer komplicerat kan du använda mer avancerade begränsningar och skapa en klass för att radera logiken:

# 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

En form, flera skicka knappar

Du kan också använda värdet på skicka taggarna i ett formulär som en begränsning för att väg till en annan åtgärd. Om du har ett formulär med flera skicka-knappar (t.ex. "förhandsvisning" och "skicka"), kan du fånga denna begränsning direkt i dina routes.rb , istället för att skriva javascript för att ändra destinationsadressen till formuläret. Till exempel med commit_param_routing pärla kan du dra nytta av rails submit_tag

Rails submit_tag första parameter låter dig ändra värdet på din formuläråtgärdsparameter

# 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

Omfattningsvägar

Rails ger flera sätt att organisera dina rutter.

Räckvidd efter URL :

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

Detta genererar följande rutter

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'

Det kan vara mer meningsfullt, på serversidan, att behålla vissa vyer i en annan undermapp, att separera adminvyer från användarvyer.

Omfattning efter modul

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

module letar efter kontrollfilerna under undermappen med det givna namnet

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

Du kan byta namn på väg hjälpare prefix genom att lägga till en as parameter

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

# => administration_dashboard_path

Rails är ett bekvämt sätt att göra allt ovan med hjälp av namespace . Följande förklaringar är likvärdiga

namespace :admin do
end

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

Omfattning av styrenheten

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

Detta genererar dessa rutter

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

Grunt bo

Resursvägar accepterar ett :shallow alternativ som hjälper till att förkorta webbadresser där det är möjligt. Resurser bör inte häckas mer än en nivå djup. Ett sätt att undvika detta är genom att skapa grunda rutter. Målet är att släppa URL-segment från förälderssamlingen där de inte behövs. Slutresultatet är att de enda kapslade rutter som genereras är för :index :create och :new åtgärder. Resten förvaras i sitt eget grunt URL-sammanhang. Det finns två alternativ för räckvidd för anpassade grunda rutter:

  • : grunt_väg: Prefixerar medlemsvägar med en specificerad parameter

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : grunt_prefix : Lägg till specificerade parametrar till nämnda hjälpare

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

Vi kan också illustrera shallow rutter mer genom:

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

alternativt kodas enligt följande (om du är blocklycklig):

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

De resulterande vägarna är:

Prefix Verb URI-mönster
bid_comments SKAFFA SIG /bids/:bid_id/comments(.:format)
POSTA /bids/:bid_id/comments(.:format)
new_bid_comment SKAFFA SIG /bids/:bid_id/comments/new(.:format)
edit_comment SKAFFA SIG /comments/:id/edit(.:format)
kommentar SKAFFA SIG /comments/:id(.:format)
LAPPA /comments/:id(.:format)
SÄTTA /comments/:id(.:format)
RADERA /comments/:id(.:format)
auction_bids SKAFFA SIG /auctions/:auction_id/bids(.:format)
POSTA /auctions/:auction_id/bids(.:format)
new_auction_bid SKAFFA SIG /auctions/:auction_id/bids/new(.:format)
edit_bid SKAFFA SIG /bids/:id/edit(.:format)
bud SKAFFA SIG /bids/:id(.:format)
LAPPA /bids/:id(.:format)
SÄTTA /bids/:id(.:format)
RADERA /bids/:id(.:format)
auktioner SKAFFA SIG /auctions(.:format)
POSTA /auctions(.:format)
new_auction SKAFFA SIG /auctions/new(.:format)
edit_auction SKAFFA SIG /auctions/:id/edit(.:format)
auktion SKAFFA SIG /auctions/:id(.:format)
LAPPA /auctions/:id(.:format)
SÄTTA /auctions/:id(.:format)
RADERA /auctions/:id(.:format)

Om du analyserar de rutter som genererats noggrant kommer du att märka att de kapslade delarna av URL: en endast inkluderas när de behövs för att avgöra vilken information som ska visas.

oro

För att undvika upprepning i kapslade rutter är bekymmer ett bra sätt att dela gemensamma resurser som är återanvändbara. För att skapa en oro använda metoden concern inom routes.rb filen. Metoden förväntar sig en symbol och ett block:

concern :commentable do
  resources :comments
end

Medan man inte skapar några rutter i sig, tillåter denna kod attributet :concerns på en resurs. Det enklaste exemplet skulle vara:

resource :page, concerns: :commentable

Den motsvarande kapslade resursen ser ut så här:

resource :page do
  resource :comments
end

Detta skulle till exempel bygga följande rutter:

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

För att bekymmer ska vara meningsfulla måste det finnas flera resurser som utnyttjar oroen. Ytterligare resurser kan använda någon av följande syntaxer för att ringa problemet:

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

Omdirigering

Du kan utföra omdirigering i Rails-rutter enligt följande:

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

Du kan också omdirigera alla okända rutter till en given väg:

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

Medlemmar och samlingar

Att definiera ett medlemsblock inuti en resurs skapar en rutt som kan agera på en enskild medlem av den resursbaserade rutten:

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

Detta genererar följande medlemsväg:

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

Samlingsvägar gör det möjligt att skapa rutter som kan agera på en samling resursobjekt:

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

Detta genererar följande insamlingsväg:

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

En alternativ syntax:

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

URL-parametrar med en period

Om du vill stödja en url-parameter som är mer komplex än ett ID-nummer kan du stöta på problem med parsaren om värdet innehåller en period. Allt efter en period antas vara ett format (dvs json, xml).

Du kan lösa denna begränsning genom att använda en begränsning för att bredda den accepterade inmatningen.

Om du till exempel vill hänvisa till en användarpost via e-postadress i url:

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

Rotväg

Du kan lägga till en hemsidesrutt till din app med 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

Och i terminalen kommer rake routes ( rails routes i Rails 5) att producera:

root     GET    /         application#index

Eftersom hemsidan är oftast den viktigaste vägen och vägar prioriteras i den ordning de visas i root bör vägen brukar vara den första i rutter fil.

Ytterligare RESTful handlingar

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

Detta skapar följande rutter utöver standard 7 RESTful rutter :

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

Om du vill göra detta för enstaka rader kan du använda:

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

Du kan också lägga till en åtgärd på /new sökväg:

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

Vilket skapar:

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

Var uppmärksam när du lägger till åtgärder till dina RESTful rutter, förmodligen saknar du en annan resurs!

Tillgängliga platser

Om din ansökan är tillgänglig på olika språk visar du vanligtvis det aktuella språket i URL: en.

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

Din rot kommer att vara tillgänglig via de platser som definieras i I18n.available_locales .

Montera en annan applikation

mount används för att montera en annan applikation (i princip rackapplikation) eller rälsmotorer som ska användas inom den aktuella applikationen

syntax:

mount SomeRackApp, at: "some_route"

Nu kan du komma åt ovanstående monterad applikation med hjälp av some_rack_app_path eller some_rack_app_url .

Men om du vill byta namn på detta hjälparnamn kan du göra det som:

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

Detta genererar myapp_path och myapp_url som kan användas för att navigera till denna monterade app.

Omdirigeringar och jokerteckenrutter

Om du vill ange en URL av bekvämlighet för din användare men kartlägga den direkt till en annan som du redan använder. Använd en omdirigering:

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

Det blev intressant snabbt. Den grundläggande principen här är att bara använda #redirect metoden för att skicka en rutt till en annan rutt. Om din rutt är ganska enkel är det en riktigt enkel metod. Men om du också vill skicka de ursprungliga parametrarna måste du göra lite gymnastik genom att fånga parametern inuti %{here} . Notera de enskilda citaten kring allt.

I exemplet ovan har vi också bytt namn på rutten för enkelhets skull genom att använda ett alias med parametern: som. Detta låter oss använda det namnet på metoder som #_path-hjälpare. Testa igen dina $ rake routes med frågor.

Dela rutter i flera filer

Om din ruttfil är överväldigande stor kan du lägga dina rutter i flera filer och inkludera var och en av filerna med Rubys require_relative metod:

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

Kapslade rutter

Om du vill lägga till kapslade rutter kan du skriva följande kod i filen routes.rb .

resources :admins do
  resources :employees
end

Detta genererar följande rutter:

     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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow