Szukaj…


Wprowadzenie

Router Railsów rozpoznaje adresy URL i wysyła je do akcji kontrolera. Może także generować ścieżki i adresy URL, unikając konieczności wpisywania ciągów kodu w twoich widokach.

Uwagi

„Routing” ogólnie to, w jaki sposób adresy URL są „obsługiwane” przez aplikację. W przypadku Rails zazwyczaj jest to, który kontroler i która akcja tego kontrolera obsłuży dany przychodzący adres URL. W aplikacjach Railsowych trasy są zwykle umieszczane w config/routes.rb .

Routing zasobów (podstawowy)

Trasy są zdefiniowane w config/routes.rb . Często są one definiowane jako grupa powiązanych tras, przy użyciu resources lub metod resource .

resources :users tworzą następujące siedem tras, wszystkie mapowane na działania 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'

Nazwy akcji są wyświetlane po znaku # w parametrze to powyżej. Metody o tych samych nazwach należy zdefiniować w app/controllers/users_controller.rb w następujący sposób:

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

Możesz ograniczyć akcje generowane only lub except :

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

Możesz wyświetlić wszystkie trasy swojej aplikacji w dowolnym momencie, uruchamiając:

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

Aby wyświetlić tylko trasy mapowane na konkretny kontroler:

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

Możesz przeszukiwać trasy za pomocą opcji -g . To pokazuje dowolną trasę, która częściowo pasuje do nazwy metody pomocnika, ścieżki URL lub czasownika 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 

Dodatkowo, kiedy serwer rails w trybie programowania, możesz uzyskać dostęp do strony internetowej, która pokazuje wszystkie twoje trasy z filtrem wyszukiwania, dopasowanym priorytetem od góry do dołu, w <hostname>/rails/info/routes . Będzie to wyglądać tak:

Pomocnik Czasownik HTTP Ścieżka Kontroler nr Działanie
Ścieżka / adres URL [Ścieżka dopasowania]
ścieżka_użytkowników OTRZYMAĆ /users(.:format) liczba użytkowników #
POCZTA /users(.:format) użytkownicy # tworzą
nowa_ścieżka_użytkownika OTRZYMAĆ /users/new(.:format) użytkownicy # nowi
edit_user_path OTRZYMAĆ /users/:id/edit(.:format) użytkownicy # edytuj
ścieżka_użytkownika OTRZYMAĆ /users/:id(.:format) użytkownicy # pokaż
ŁATA /users/:id(.:format) aktualizacja # użytkowników
POŁOŻYĆ /users/:id(.:format) aktualizacja # użytkowników
USUNĄĆ /users/:id(.:format) użytkownicy # zniszczą

Trasy mogą być uznane za dostępne jedynie dla członków (nie zbiorów) stosując metodę resource zamiast resources w routes.rb . W przypadku resource trasa index nie jest tworzona domyślnie, ale tylko wtedy, gdy jawnie poprosi o taką:

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

Ograniczenia

Możesz filtrować dostępne trasy za pomocą ograniczeń.

Istnieje kilka sposobów korzystania z ograniczeń, w tym:

Na przykład żądanie oparte na ograniczeniu, aby zezwolić tylko określonemu adresowi IP na dostęp do trasy:

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

Zobacz inne podobne przykłady ActionDispatch :: Routing :: Mapper :: Scoping .

Jeśli chcesz zrobić coś bardziej złożonego, możesz użyć bardziej zaawansowanych ograniczeń i utworzyć klasę do zawarcia logiki:

# 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

Jeden formularz, kilka przycisków przesyłania

Możesz także użyć wartości tagów przesyłania formularza jako ograniczenia do kierowania do innej akcji. Jeśli masz formularz z wieloma przyciskami przesyłania (np. „Podgląd” i „prześlij”), możesz przechwycić to ograniczenie bezpośrednio w routes.rb , zamiast pisać javascript, aby zmienić docelowy adres URL formularza. Na przykład z klejnotem commit_param_routing możesz skorzystać z szyn submit_tag

Pierwszy parametr Rails submit_tag pozwala zmienić wartość parametru formularza zatwierdzenia formularza

# 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

Określanie tras

Railsy zapewniają kilka sposobów organizacji tras.

Zakres według adresu URL :

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

To generuje następujące trasy

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'

Po stronie serwera bardziej sensowne może być przechowywanie niektórych widoków w innym podfolderze, aby oddzielić widoki administratora od widoków użytkownika.

Zakres według modułu

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

module szuka plików kontrolera w podfolderze o podanej nazwie

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

Możesz zmienić nazwę prefiksu helpers ścieżki, dodając parametr as

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

# => administration_dashboard_path

Railsy to wygodny sposób na wykonanie powyższych czynności przy użyciu metody namespace . Poniższe deklaracje są równoważne

namespace :admin do
end

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

Zakres według kontrolera

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

To generuje te trasy

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

Płytkie zagnieżdżanie

Trasy zasobów akceptują :shallow opcję, która pomaga skracać adresy URL tam, gdzie to możliwe. Zasoby nie powinny być zagnieżdżone na głębokości większej niż jeden poziom. Jednym ze sposobów uniknięcia tego jest tworzenie płytkich tras. Celem jest pozostawienie segmentów adresów URL kolekcji nadrzędnej tam, gdzie nie są one potrzebne. W rezultacie generowane są tylko zagnieżdżone trasy dla akcji :index :create i :new . Reszta jest przechowywana we własnym kontekście płytkiego adresu URL. Istnieją dwie opcje zakresu niestandardowych płytkich tras:

  • : shallow_path: Prefiksuje ścieżki członków określonym parametrem

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : shallow_prefix : Dodaj określone parametry do nazwanych pomocników

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

shallow trasy możemy też lepiej zilustrować poprzez:

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

alternatywnie kodowane w następujący sposób (jeśli jesteś zadowolony z bloku):

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

Wynikowe trasy to:

Prefiks Czasownik Wzór URI
bid_comments OTRZYMAĆ /bids/:bid_id/comments(.:format)
POCZTA /bids/:bid_id/comments(.:format)
new_bid_comment OTRZYMAĆ /bids/:bid_id/comments/new(.:format)
edit_comment OTRZYMAĆ /comments/:id/edit(.:format)
komentarz OTRZYMAĆ /comments/:id(.:format)
ŁATA /comments/:id(.:format)
POŁOŻYĆ /comments/:id(.:format)
USUNĄĆ /comments/:id(.:format)
licytacja OTRZYMAĆ /auctions/:auction_id/bids(.:format)
POCZTA /auctions/:auction_id/bids(.:format)
nowa oferta OTRZYMAĆ /auctions/:auction_id/bids/new(.:format)
edit_bid OTRZYMAĆ /bids/:id/edit(.:format)
stawka OTRZYMAĆ /bids/:id(.:format)
ŁATA /bids/:id(.:format)
POŁOŻYĆ /bids/:id(.:format)
USUNĄĆ /bids/:id(.:format)
aukcje OTRZYMAĆ /auctions(.:format)
POCZTA /auctions(.:format)
nowa_ukukcja OTRZYMAĆ /auctions/new(.:format)
edycja_ukcji OTRZYMAĆ /auctions/:id/edit(.:format)
Aukcja OTRZYMAĆ /auctions/:id(.:format)
ŁATA /auctions/:id(.:format)
POŁOŻYĆ /auctions/:id(.:format)
USUNĄĆ /auctions/:id(.:format)

Jeśli dokładnie przeanalizujesz wygenerowane trasy, zauważysz, że zagnieżdżone części adresu URL są uwzględniane tylko wtedy, gdy są potrzebne do ustalenia, jakie dane mają zostać wyświetlone.

Obawy

Aby uniknąć powtórzeń w zagnieżdżonych trasach, obawy zapewniają świetny sposób udostępniania wspólnych zasobów, które można ponownie wykorzystać. Aby utworzyć koncern użyć metody concern obrębie routes.rb pliku. Metoda oczekuje symbolu i bloku:

concern :commentable do
  resources :comments
end

Chociaż sam nie tworzy żadnych tras, ten kod umożliwia użycie atrybutu :concerns zasobu. Najprostszym przykładem byłoby:

resource :page, concerns: :commentable

Odpowiednik zagnieżdżonego zasobu wyglądałby następująco:

resource :page do
  resource :comments
end

Spowodowałoby to na przykład utworzenie następujących tras:

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

Aby obawy były znaczące, musi istnieć wiele zasobów, które wykorzystują obawy. Dodatkowe zasoby mogą użyć dowolnej z następujących składni, aby wywołać problem:

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

Przekierowanie

Możesz wykonać przekierowanie na trasach Rails w następujący sposób:

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

Możesz również przekierować wszystkie nieznane trasy na podaną ścieżkę:

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

Trasy członków i kolekcji

Zdefiniowanie bloku elementu w zasobie powoduje utworzenie trasy, która może działać na poszczególnych elementach tej trasy opartej na zasobach:

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

To generuje następującą trasę członka:

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

Trasy kolekcji umożliwiają tworzenie tras, które mogą działać na kolekcji obiektów zasobów:

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

Generuje to następującą trasę zbierania:

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

Alternatywna składnia:

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

Parametry adresu URL z kropką

Jeśli chcesz obsługiwać parametr adresu URL bardziej złożony niż numer identyfikacyjny, możesz mieć problemy z analizatorem składni, jeśli wartość zawiera kropkę. Wszystko, co następuje po kropce, zostanie uznane za format (tj. Json, xml).

Można obejść to ograniczenie, używając ograniczenia w celu rozszerzenia akceptowanych danych wejściowych.

Na przykład, jeśli chcesz odwołać się do rekordu użytkownika przez adres e-mail w adresie URL:

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

Root route

Możesz dodać trasę do strony głównej do swojej aplikacji za pomocą metody 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

A w terminalu rake routes ( rails routes w Railsach 5) wygenerują:

root     GET    /         application#index

Ponieważ strona jest zazwyczaj najważniejszą drogą, a trasy są traktowane priorytetowo w kolejności ich występowania The root trasa powinna zwykle być pierwszym w swoim pliku trasach.

Dodatkowe działania RESTful

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

Tworzy to następujące trasy oprócz domyślnych 7 tras RESTful :

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

Jeśli chcesz to zrobić dla pojedynczych linii, możesz użyć:

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

Możesz także dodać akcję do /new ścieżki:

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

Co stworzy:

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

Pamiętaj o dodawaniu działań do tras RESTful, prawdopodobnie brakuje Ci innego zasobu!

Zakres dostępnych lokalizacji

Jeśli Twoja aplikacja jest dostępna w różnych językach, zwykle wyświetlasz bieżące ustawienia regionalne w adresie URL.

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

Twój katalog główny będzie dostępny za pośrednictwem ustawień I18n.available_locales zdefiniowanych w I18n.available_locales .

Zamontuj inną aplikację

mount służy do montowania innej aplikacji (w zasadzie aplikacji do montażu w szafie) lub silników szynowych do użycia w bieżącej aplikacji

składnia:

mount SomeRackApp, at: "some_route"

Teraz możesz uzyskać dostęp do zamontowanej aplikacji za pomocą pomocnika trasy some_rack_app_path lub some_rack_app_url .

Ale jeśli chcesz zmienić nazwę tej nazwy pomocnika, możesz to zrobić jako:

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

Spowoduje to wygenerowanie pomocników myapp_path i myapp_url których można użyć do nawigacji do tej zamontowanej aplikacji.

Przekierowania i trasy wieloznaczne

Jeśli chcesz podać adres URL, który nie jest dla ciebie wygodny, ale zamapuj go bezpośrednio na inny, którego już używasz. Użyj przekierowania:

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

To szybko stało się interesujące. Podstawową zasadą jest tutaj użycie metody #redirect , aby wysłać jedną trasę na inną. Jeśli twoja trasa jest dość prosta, jest to naprawdę prosta metoda. Ale jeśli chcesz również przesłać oryginalne parametry, musisz trochę poćwiczyć, przechwytując parametr wewnątrz %{here} . Zwróć uwagę na pojedyncze cytaty wokół wszystkiego.

W powyższym przykładzie zmieniliśmy również nazwę trasy dla wygody, używając aliasu z parametrem: as. To pozwala nam używać tej nazwy w metodach takich jak pomocnicy #_path. Ponownie przetestuj swoje $ rake routes z pytaniami.

Podziel trasy na wiele plików

Jeśli twój plik tras jest przeważnie duży, możesz umieścić swoje trasy w wielu plikach i dołączyć każdy z nich za pomocą metody require_relative przez Ruby'ego:

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

Zagnieżdżone trasy

Jeśli chcesz dodać zagnieżdżone trasy, możesz napisać następujący kod w routes.rb .

resources :admins do
  resources :employees
end

Spowoduje to wygenerowanie następujących tras:

     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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow