Ruby on Rails
Wytyczanie
Szukaj…
Wprowadzenie
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:
$ rake routes
$ 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:
$ 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
$ 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:
$ rake routes -g new_user # Matches helper method
$ rake routes -g POST # Matches HTTP Verb POST
$ 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:
get '/stories', to: redirect('/posts')
match "/abc" => redirect("http://example.com/abc")
Możesz również przekierować wszystkie nieznane trasy na podaną ścieżkę:
match '*path' => redirect('/'), via: :get
# or
get '*path' => redirect('/')
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