Zoeken…


Invoering

De Rails-router herkent URL's en verzendt deze naar de actie van een controller. Het kan ook paden en URL's genereren, waardoor het niet nodig is om strings in uw weergaven hard te coderen.

Opmerkingen

'Routing' is in het algemeen hoe URL's door uw app worden 'verwerkt'. In het geval van Rails is het meestal welke controller en welke actie van die controller een bepaalde inkomende URL verwerkt. In Rails-apps worden routes meestal in het bestand config/routes.rb .

Resource routing (basis)

Routes worden gedefinieerd in config/routes.rb . Ze worden vaak gedefinieerd als een groep verwante routes, met behulp van de resources of resource methoden.

resources :users maakt de volgende zeven routes, alle toewijzingen aan acties van 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'

Actienamen worden weergegeven na het # in de parameter to hierboven. Methoden met dezelfde namen moeten als volgt worden gedefinieerd in app/controllers/users_controller.rb :

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

U kunt de acties beperken die worden gegenereerd met only of except :

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

U kunt op elk gewenst moment alle routes van uw applicatie bekijken door te draaien:

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

Alleen de routes bekijken die naar een bepaalde controller verwijzen:

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

U kunt routes doorzoeken met de optie -g . Dit toont elke route die gedeeltelijk overeenkomt met de naam van de helpermethode, het URL-pad of het HTTP-werkwoord:

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 

Bovendien kunt u, wanneer u rails server in de ontwikkelingsmodus gebruikt, toegang krijgen tot een webpagina waarop al uw routes worden weergegeven met een zoekfilter, van boven naar beneden afgestemd op <hostname>/rails/info/routes . Het ziet er zo uit:

Helper HTTP Verb Pad Controller # Actie
Pad / URL [Padovereenkomst]
users_path KRIJGEN /users(.:format) gebruikers # index
POST /users(.:format) gebruikers # maak
new_user_path KRIJGEN /users/new(.:format) gebruikers # nieuwe
edit_user_path KRIJGEN /users/:id/edit(.:format) gebruikers # bewerken
user_path KRIJGEN /users/:id(.:format) gebruikers # tonen
PATCH /users/:id(.:format) gebruikers #-update
LEGGEN /users/:id(.:format) gebruikers #-update
DELETE /users/:id(.:format) gebruikers # vernietigen

Routes kunnen alleen beschikbaar worden verklaard voor leden (geen collecties) met behulp van de methode resource plaats van resources in routes.rb . Met resource wordt een index niet standaard gemaakt, maar alleen wanneer expliciet om een dergelijke wordt gevraagd:

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

constraints

U kunt filteren welke routes beschikbaar zijn met behulp van beperkingen.

Er zijn verschillende manieren om beperkingen te gebruiken, waaronder:

Een aangevraagde gebaseerde beperking om alleen een specifiek IP-adres toegang te geven tot een route:

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

Bekijk andere soortgelijke voorbeelden ActionDispatch :: Routing :: Mapper :: Scoping .

Als je iets complexers wilt doen, kun je geavanceerdere beperkingen gebruiken en een klasse maken om de logica te omzeilen:

# 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

Eén formulier, meerdere verzendknoppen

U kunt ook de waarde van de verzendtags van een formulier gebruiken als beperking om naar een andere actie te routeren. Als u een formulier hebt met meerdere verzendknoppen (bijv. "Preview" en "submit"), kunt u deze beperking direct in uw routes.rb , in plaats van javascript te schrijven om de bestemmings-URL van het formulier te wijzigen. Met de commit_param_routing- edelsteen kun je bijvoorbeeld profiteren van rails submit_tag

Met Rails submit_tag first parameter kunt u de waarde van uw formulier commit parameter wijzigen

# 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

Scope routes

Rails biedt verschillende manieren om uw routes te organiseren.

Bereik op URL :

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

Dit genereert de volgende routes

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'

Het kan logischer zijn, aan de serverzijde, om sommige views in een andere submap te houden, om admin views van gebruikers views te scheiden.

Bereik per module

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

module zoekt naar de controllerbestanden onder de submap van de opgegeven naam

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

U kunt de prefix padhelpers hernoemen door een parameter as toe te voegen

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

# => administration_dashboard_path

Rails biedt een handige manier om al het bovenstaande te doen, met behulp van de namespace . De volgende verklaringen zijn gelijkwaardig

namespace :admin do
end

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

Bereik per controller

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

Dit genereert deze routes

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

Ondiep nestelen

Bronroutes accepteren een :shallow optie die helpt om URL's waar mogelijk in te korten. Bronnen mogen niet meer dan één niveau diep worden genest. Een manier om dit te voorkomen is door ondiepe routes te maken. Het doel is om URL-segmenten van bovenliggende collecties weg te laten waar ze niet nodig zijn. Het eindresultaat is dat de enige gegenereerde geneste routes zijn voor de :index :create en :new actions. De rest wordt bewaard in hun eigen ondiepe URL-context. Er zijn twee opties voor bereik tot aangepaste ondiepe routes:

  • : shallow_path: prefixeert lidpaden met een opgegeven parameter

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : shallow_prefix : voeg gespecificeerde parameters toe aan genoemde helpers

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

We kunnen shallow routes ook meer illustreren door:

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

alternatief gecodeerd als volgt (als je tevreden bent met de blokken):

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

De resulterende routes zijn:

Voorvoegsel Werkwoord URI-patroon
bid_comments KRIJGEN /bids/:bid_id/comments(.:format)
POST /bids/:bid_id/comments(.:format)
new_bid_comment KRIJGEN /bids/:bid_id/comments/new(.:format)
edit_comment KRIJGEN /comments/:id/edit(.:format)
commentaar KRIJGEN /comments/:id(.:format)
PATCH /comments/:id(.:format)
LEGGEN /comments/:id(.:format)
DELETE /comments/:id(.:format)
auction_bids KRIJGEN /auctions/:auction_id/bids(.:format)
POST /auctions/:auction_id/bids(.:format)
new_auction_bid KRIJGEN /auctions/:auction_id/bids/new(.:format)
edit_bid KRIJGEN /bids/:id/edit(.:format)
bod KRIJGEN /bids/:id(.:format)
PATCH /bids/:id(.:format)
LEGGEN /bids/:id(.:format)
DELETE /bids/:id(.:format)
veilingen KRIJGEN /auctions(.:format)
POST /auctions(.:format)
new_auction KRIJGEN /auctions/new(.:format)
edit_auction KRIJGEN /auctions/:id/edit(.:format)
veiling KRIJGEN /auctions/:id(.:format)
PATCH /auctions/:id(.:format)
LEGGEN /auctions/:id(.:format)
DELETE /auctions/:id(.:format)

Als u de gegenereerde routes zorgvuldig analyseert, zult u merken dat de geneste delen van de URL alleen worden opgenomen wanneer ze nodig zijn om te bepalen welke gegevens moeten worden weergegeven.

Bedenkingen

Om herhaling in geneste routes te voorkomen, bieden zorgen een geweldige manier om gemeenschappelijke bronnen te delen die herbruikbaar zijn. Gebruik de methode concern in het bestand routes.rb om een probleem te creëren. De methode verwacht een symbool en blok:

concern :commentable do
  resources :comments
end

Hoewel er zelf geen routes worden gemaakt, kunt u met deze code het kenmerk :concerns op een resource gebruiken. Het eenvoudigste voorbeeld zou zijn:

resource :page, concerns: :commentable

De equivalente geneste bron ziet er als volgt uit:

resource :page do
  resource :comments
end

Dit zou bijvoorbeeld de volgende routes bouwen:

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

Wil bezorgdheid zinvol zijn, dan moeten er meerdere bronnen zijn die de zorg gebruiken. Aanvullende bronnen kunnen een van de volgende syntaxis gebruiken om het probleem op te lossen:

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

Redirection

U kunt omleiding in Rails-routes als volgt uitvoeren:

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

Je kunt ook alle onbekende routes omleiden naar een bepaald pad:

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

Routes voor leden en collecties

Door een ledenblok in een resource te definiëren, wordt een route gecreëerd die kan reageren op een individueel lid van die resource-gebaseerde route:

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

Dit genereert de volgende ledenroute:

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

Met verzamelingsroutes kunnen routes worden gemaakt die kunnen werken op een verzameling resourceobjecten:

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

Dit genereert de volgende verzamelroute:

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

Een alternatieve syntaxis:

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

URL-parameters met een punt

Als u een meer complexe URL-parameter dan een id-nummer wilt ondersteunen, kunt u problemen ondervinden met de parser als de waarde een punt bevat. Alles wat volgt op een punt wordt verondersteld een formaat te zijn (dwz json, xml).

U kunt deze beperking omzeilen door een beperking te gebruiken om de geaccepteerde invoer te verbreden .

Als u bijvoorbeeld wilt verwijzen naar een gebruikersrecord op e-mailadres in de url:

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

Hoofdroute

U kunt een startpaginaroute toevoegen aan uw app met de 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

En in de terminal zullen rake routes ( rails routes in Rails 5) het volgende produceren:

root     GET    /         application#index

Omdat de startpagina meestal de belangrijkste route is en routes prioriteit krijgen in de volgorde waarin ze verschijnen, moet de root route meestal de eerste zijn in je routes-bestand.

Aanvullende RESTful acties

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

Dit maakt de volgende routes naast de standaard 7 RESTful-routes :

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

Als u dit voor enkele lijnen wilt doen, kunt u het volgende gebruiken:

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

U kunt ook een actie toevoegen aan het /new pad:

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

Welke zal creëren:

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

Let op bij het toevoegen van acties aan je RESTful-routes, je mist waarschijnlijk een andere bron!

Beschikbare locaties

Als uw toepassing beschikbaar is in verschillende talen, geeft u meestal de huidige landinstelling weer in de URL.

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

Je root is toegankelijk via de landinstellingen die zijn gedefinieerd in I18n.available_locales .

Mount een andere applicatie

mount wordt gebruikt om een andere applicatie (in principe rackapplicatie) of railmotoren te monteren voor gebruik in de huidige applicatie

syntaxis:

mount SomeRackApp, at: "some_route"

Nu kunt u toegang krijgen tot de bovenstaande gemonteerde toepassing met behulp van route helper some_rack_app_path of some_rack_app_url .

Maar als u deze helpernaam wilt hernoemen, kunt u dit doen als:

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

Dit genereert de myapp_path en myapp_url helpers die kunnen worden gebruikt om naar deze gekoppelde app te navigeren.

Omleidingen en jokertekens

Als u voor uw gemak een URL wilt opgeven, maar deze rechtstreeks wilt toewijzen aan een andere URL die u al gebruikt. Gebruik een omleiding:

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

Nou, dat werd snel interessant. Het basisprincipe hier is om alleen de #redirect methode te gebruiken om de ene route naar een andere route te verzenden. Als je route vrij eenvoudig is, is het een heel eenvoudige methode. Maar als u ook de originele parameters wilt verzenden, moet u een beetje gymnastiek doen door de parameter vast te leggen in %{here} . Let op de enkele aanhalingstekens rondom alles.

In het bovenstaande voorbeeld hebben we de route voor het gemak ook hernoemd met behulp van een alias met de parameter: as. Hiermee kunnen we die naam gebruiken in methoden zoals de #_path helpers. Nogmaals, test je $ rake routes met vragen.

Split routes in meerdere bestanden

Als je routesbestand overweldigend groot is, kun je je routes in meerdere bestanden plaatsen en elk van de bestanden opnemen met Ruby's require_relative methode:

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

Geneste routes

Als u geneste routes wilt toevoegen, kunt u de volgende code in routes.rb bestand schrijven.

resources :admins do
  resources :employees
end

Dit genereert de volgende routes:

     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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow