Trasy i zasoby

podstawowe konwencje routingu

przyjrzyjmy się naszym trasom w obecnej postaci, używając rake routes:

$ rake routes Prefix Verb URI Pattern Controller#Action list_posts GET /list_posts(.:format) application#list_posts GET /show_post/:id(.:format) application#show_post new_post GET /new_post(.:format) application#new_post create_post POST /create_post(.:format) application#create_post GET /edit_post/:id(.:format) application#edit_post POST /update_post/:id(.:format) application#update_post POST /delete_post/:id(.:format) application#delete_post POST /create_comment_for_post/:post_id(.:format) application#create_comment POST /list_posts/:post_id/delete_comment/:comment_id(.:format) application#delete_comment list_comments GET /list_comments(.:format) application#list_comments 

jednym z kluczowych spostrzeżeń dotyczących konwencji Rails jest to, że aplikacje skoncentrowane na danych (lub Aplikacje CRUDy) mają bardzo podobne sposoby pozwalania użytkownikom na interakcję z aplikacją, które są:

  • strona do wyświetlenia listy czegoś
  • zobacz coś
  • Pokaż formularz do utworzenia nowej instancji czegoś
  • faktycznie Utwórz coś
  • Pokaż formularz do edycji instancji czegoś
  • faktycznie zaktualizuj coś
  • Usuń coś

te siedem „wzorców interakcji” jest tak powszechne, że rails zapewnia silny zestaw konwencji, od routingu po kontrolery, widoki i formularze, aby ułatwić te przepływy pracy. Skupmy się teraz na routingu.

w przypadku routingu, konwencja jest taka, że zamiast wymyślać wzorce URL, Rails zaleca, abyśmy uporządkowali adresy URL i odpowiadające im akcje kontrolera w następujący sposób:

Workflow czasownik HTTP ścieżka Akcja kontrolera
Pokaż listę postów Pobierz / posty posty#index
Pokaż post Pobierz / posty/:id posty # Pokaż
Pokaż stronę do utworzenia postu Pobierz / posty / nowe posty # nowe
utwórz post POST / posty posty # Utwórz
Pokaż stronę do edycji postu Pobierz / posts/: id / edit posts#edit
Update a post PUT / PATCH / posts/: id posts#update
Usuń post Usuń / posty/:id posty # destroy

możemy zmienić część post naszego obecnego routingu, aby była zgodna z tą konwencją:

# posts GET /list_posts -> GET /posts posts#index GET /show_post/:id -> GET /posts/:id posts#show GET /new_post -> GET /posts/new posts#new POST /create_post -> POST /posts posts#create GET /edit_post/:id -> GET /posts/:id/edit posts#edit POST /update_post/:id -> PUT/PATCH /posts/:id posts#update POST /delete_post/:id -> DELETE /posts/:id posts#destroy 

i w pliku routes.rb ,

Rails.application.routes.draw do ### posts ### get '/posts' => 'posts#index' get '/posts/new' => 'posts#new' get '/posts/:id' => 'posts#show' post '/posts' => 'posts#create' get '/posts/:id/edit' => 'posts#edit' patch '/posts/:id' => 'posts#update' put '/posts/:id' => 'posts#update' delete '/posts/:id' => 'posts#destroy' # comments later.. ... end 

zauważ, że w tym nowym wzorze jest o wiele mniej czasowników w samym adresie URL, ale opieramy się na czasownikach HTTP (GET/POST/PUT/PATCH/DELETE) aby podać semantykę dla tych samych wzorców URL, na przykład /posts/:id.

zauważ, że PUT był używany do aktualizacji zasobów do niedawna, kiedy PATCH uznano za lepsze dopasowanie semantyczne dla tej akcji. Od tego czasu Rails przeszedł do preferowania PATCH, ale zezwalając na aktualizacje obu czasowników.

kolejna zmiana, którą zobaczymy później, to przekierowanie wszystkich adresów URL związanych z postami na PostsController zamiast obsługi wszystkiego w ApplicationController. Nazwy akcji PostController

  • new
  • index
  • show
  • create
  • edit
  • update
  • destroy

są również konwencjami odpowiadającymi 7 interakcjom wzory.

to najsilniejszy zestaw konwencji, które Rails nakłada na Ciebie jako programistę aplikacji. Poprosimy cię, abyś spróbował go zapamiętać. Będziemy wracać do tego wiele razy w całej książce, aby pomóc ci to zrobić, jak również.

Routing dla wielu zasobów

często musimy mieć wiele zasobów obecnych w adresie URL. Na przykład w przypadku naszej aplikacji blogowej, gdy potrzebujemy trasy do utworzenia komentarza, bardzo ważne jest, abyśmy wiedzieli, na którym poście ten komentarz jest tworzony.

:

post 'create_comment_for_post/:post_id' => 'application#create_comment' 

konwencja Rails adresu URL z wieloma powiązanymi zasobami rozpoczyna się od zasobu „zawierającego” aż do zasobu „najskrytszego”. Na przykład nasze trasy komentarzy zmieniłyby się na:

post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' get '/comments' => 'comments#index' 

semantyka tych adresów URL reprezentuje: „Utwórz komentarz pod określonym postem” i „Usuń komentarz pod określonym postem”. Ostatnia trasa, „Pokaż wszystkie komentarze w systemie”, nie musi być” scoped „pod postem, więc adres URL nie musi prowadzić przez”/posts”.

jeśli potrzebujemy mieć wiele zasobów w adresie URL z ich identyfikatorami, konwencja jest taka, że ostatni zasób będzie używał symbolu zastępczego :id, a cała reszta będzie :resource_id, takich jak :post_id.

Restful

REST oznacza „transfer Państwa Reprezentacyjnego”. Jest to styl architektury oprogramowania i wytyczne do tworzenia skalowalnych usług internetowych. Reszta, jako sposób na strukturę aplikacji internetowych, ma wiele aspektów, ale spójrzmy, jak odnosi się do interfejsu, którego używamy do interakcji z aplikacjami internetowymi, adresów URL.

aby zobaczyć, jak REST upraszcza semantykę adresów URL, przejdźmy przez przykład. Załóżmy, że budujemy usługę zamawiania pizzy online. Naiwna implementacja interfejsów serwisu (adresów URL) byłaby:

/check_order?order_id=2 /place_new_order /pizza_details?type=1 /pay_for_my_order?order_id=12 /cancel_order?order_id=3 /expedite_order?order_id=13 

RESTful projekt interfejsu wyglądałby tak:

GET /orders/2 POST /orders GET /pizzas/1 POST /orders/12/payments DELETE /orders/3 POST /orders/13/expeditions 

jak widać, Interfejsy RESTful skupiają się wokół „rzeczowników” lub „zasobów”, usuwając „czasowniki” z interfejsów, ale polegając na standardowych czasownikach HTTP(GET/POST/PUT/DELETE) dostarczenie semantyki CRUD do działań. Czasowniki takie jak check, place, cancel są mapowane bezpośrednio do czasowników HTTP GET, aby pobrać, POST aby utworzyć i DELETE aby zniszczyć zasób order. pay i expedite są skonstruowane jako tworzenie (HTTP POST) zasobów podrzędnych payments i expeditionspod zasobem orders.

Interfejsy RESTful ustandaryzowane wzorce interakcji aplikacji internetowych, aby ułatwić ich zrozumienie i zaprogramowanie. Ponieważ interfejsy skupiają się na manipulowaniu zasobami, odpowiedzi są znacznie bardziej przewidywalne. Analogią tego, w jaki sposób schemat architektury RESTful upraszcza interakcję z usługami sieciowymi, jest sposób, w jaki relacyjna baza danych i język SQL upraszczają przechowywanie danych. Przed relacyjną bazą danych i SQL dane były zazwyczaj przechowywane w systemach zastrzeżonych z określoną logiką interakcji z nimi, oznaczało to, że w każdym projekcie trzeba było nauczyć się innego zestawu instrukcji do interakcji z danymi. Relacyjne bazy danych i SQL dały wspólną strukturę danych (rekordy danych jako wiersze i kolumny przechowywane w tabelach) oraz zestaw wspólnych interfejsów-cztery proste czasowniki SELECT, INSERT, UPDATE i DELETE, które mogą obsługiwać wszystkie typy aplikacji.

zastosowanie interfejsu RESTful dla Twojej aplikacji internetowej usprawni również Twoją aplikację, aby dostosować ją do sposobu przechowywania danych zaplecza w bazach danych, i ułatwi tworzenie aplikacji. Zobaczymy to w kolejnych rozdziałach.

notacja zasobów

rozmawialiśmy o konwencjach routingu Rails i wzorcach RESTful URL. Teraz nasz plik routes.rb wyglądałby następująco:

### config/routes.rb ### Rails.application.routes.draw do ### posts ### get '/posts' => 'posts#index' get '/posts/new' => 'posts#new' get '/posts/:id' => 'posts#show' post '/posts' => 'posts#create' get '/posts/:id/edit' => 'posts#edit' patch '/posts/:id' => 'posts#update' put '/posts/:id' => 'posts#update' delete '/posts/:id' => 'posts#destroy' ### comments ### get '/comments' => 'comments#index' post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' end 

w rzeczywistości trasy, takie jak te, które mamy w sekcji posts, są bardzo powszechne, więc Rails zapewnia specjalną notację resources, która pomaga wygenerować je dla Ciebie.

możemy po prostu zrobić:

resources :posts 

ta linia automatycznie wygeneruje 8 linii, które mieliśmy wcześniej. Zauważ, że dla akcji update, Rails dopuszcza zarówno czasownik PUT, jak i PATCH, ze względu na kompatybilność.

możesz uruchomić bundle exec rake routes w środowisku wiersza poleceń, aby sprawdzić, czy generuje on dokładnie ten sam zestaw tras.

zauważ, że ta pojedyncza linia wygeneruje 8 tras. W naszym przypadku potrzebujemy tutaj wszystkich tras, ale jeśli potrzebujesz tylko podzbioru tras, możesz zdefiniować je bardziej wyraźnie jako:

resources :posts, only: 

ta linia powyżej wygeneruje tylko 3 trasy dla Ciebie-wpisz bundle exec rake routes, aby to sprawdzić.

zagnieżdżone zasoby

Rails pozwala nam również zagnieżdżać zasoby do tworzenia wzorców URL z wieloma zasobami, patrz poniżej:

### config/routes.rb ### Rails.application.routes.draw do resources :posts do resources :comments, only: end resources :comments, only: :index end 

Uruchom bundle exec rake routes i zobacz wyjście-powinno być takie samo jak wcześniej.

Pomocnicy ścieżek

po uruchomieniu bundle exec rake routes zwróć uwagę na kolumnę Prefix dla niektórych z tych tras. Są one tutaj, aby pomóc nam dowiedzieć się, jak korzystać z pomocników ścieżek dostarczanych przez Rails na naszych trasach. Możemy użyć tych prefiksów, po których następuje _path w naszych kontrolerach i widokach, aby łatwo budować ścieżki.

na przykład:

posts_path # => '/posts' post_id = 123 post_comments_path(post_id) # => '/posts/123/comments' 

Jaka jest zaleta używania pomocników URL, zamiast twardego kodowania ścieżek, takich jak /posts/123/comments bezpośrednio w kodzie? (na przykład w akcji kontrolera?) Powodem, dla którego chcesz używać pomocników ścieżek, jest to, że jeśli chcesz zmienić wzorce URL w aplikacji, o wiele łatwiej jest użyć pomocników URL, aby zwrócić inną ścieżkę – spójrzmy na przykład:

get '/register', to: 'users#new', as: 'register' 

kiedy dodamy klauzulę ” as ” do tej trasy, jeśli uruchomisz bundle exec rake routes, zobaczysz kolumnę Prefix z register i możesz użyć register_path, aby uzyskać /register ścieżkę. Teraz, jeśli chcemy zmienić ścieżkę na /login, wystarczy, że:

get '/login', to: 'users#new', as: 'register' 

teraz nasz register_path daje nam /login. Nie musimy w ogóle zmieniać naszego kodu w aplikacji Rails.

więcej Konwencji routingu

zanim przejdziemy dalej, rzućmy okiem na kilka odmian tego, co już widzieliśmy, a także kilka innych funkcji dostępnych dla nas w routingu Rails:

### config/routes.rb ### Rails.application.routes.draw do # pointing our homepage (root path) to posts#index root to: 'posts#index' # `match` & `via:` allow us to define one route and use several HTTP verbs # `as:` lets us define the name of the route prefix match '/authors/:id' => 'authors#update', via: , as: :update_author # update_author PUT|PATCH /authors/:id(.:format) authors#update resources :posts do # define extra params to pass for requests to a route get 'popular', on: :collection, action: :index, popular: true # popular_posts GET /posts/popular(.:format) posts#index {:popular=>true} get 'preview', on: :member # ... end # we can even use routes to redirect get '/home', to: redirect('/') end 

Podzielmy wszystkie funkcje wymienione powyżej po kolei.

  • root: root służy do określenia, jakie mapy akcji ” /”(adres URL najwyższego poziomu naszej witryny, który nie ma ścieżki).Główny adres URL witryny / aplikacji jest najczęściej używany, ponieważ root powinien być określony na górze pliku routes.

  • mecz + via: match służy do dopasowania wzorców URL do jednej lub więcej tras. Możemy również określić, który czasownik HTTP może być użyty do dopasowania do adresu URL z tym wzorcem. Robimy to przekazując hash do metody match. Kluczem do tego skrótu jest via, a wartością jest tablica czasowników HTTP. match jest bardziej ogólną formą niektórych powszechnie używanych metod routingu HTTP, takich jak get, post i delete. Może wymagać wszystkich tych samych opcji, co te metody, ale w porównaniu z tymi metodami daje nieco większą elastyczność.
    na przykład, używając match możemy określić adres URL pasujący do dwóch różnych tras, z których każda odpowiada dwóm różnym czasownikom HTTP. Normalnie, robienie tego wymagałoby dwóch komend, zamiast jednej. Możemy to zobaczyć w naszym przykładzie powyżej, gdzie dopasowujemy wzorzec URL '/authors/:id'do akcji 'authors#update'. Następnie określamy, jakie czasowniki HTTP mogą być użyte do wysłania żądania dla tego adresu URL za pomocą via: . Zawsze określaj metodę HTTP podczas używania match, nie robienie tego może mieć negatywny wpływ na bezpieczeństwo aplikacji.
    match prezentuje inną opcję routingu do określonych akcji w Rails. Ogólnie rzecz biorąc, najlepiej jest trzymać się powszechnie stosowanych metod HttpHelpers, takich jak geti post.

  • as: wspomnieliśmy nieco wcześniej, że opcja as: może być używana z naszą deklaracją trasy do zmiany prefiksu dla naszych pomocników URL. Można to wykorzystać na różne sposoby. Możemy użyć as:, aby nasi pomocnicy URL lepiej dopasowywali niestandardowe adresy URL. Innym zastosowaniem jest zmiana bieżącego pomocnika ścieżki URL na coś bardziej intuicyjnego lub coś, co lepiej pasuje do zasobów w aplikacji.

  • trasa zbierania: zobacz, jak powyżej zagnieżdżamy naszą trasę /popular pod zasobem posts. Następnie używamy on: :collection, aby określić, w jakiej części zasobu zagnieżdżamy tę trasę. Mamy wiele postów, więc jest to uważane za kolekcję. Określając on: :collectionmówimy, „Dopasuj adres URL do ścieżki /posts/popular.”Jeśli nie dodaliśmy on: :collection, Rails założy, że ta trasa odpowiada innemu zasobowi powiązanemu z jednym członkiem naszej kolekcji posts. W takim przypadku nasza trasa byłaby /posts/:id/popular. Możemy również określić wiele tras kolekcji za pomocą formatu blokowego.

collection do get 'popular' end 
  • przekazanie dodatkowego parametru: możemy określić domyślny parametr, który zawsze jest przekazywany z naszym skrótem params, gdy jesteśmy dopasowani do określonych adresów URL. Istnieją dwa sposoby określenia tego; jeden sposób jest taki sam jak powyżej:
get 'popular', on: :collection, action: :index, popular: true 

popular: true zostanie przekazana do naszej akcji, z którą popularna trasa pasuje za pomocą skrótu params. Będzie miał klucz :popular i wartość true. Możemy również użyć bardziej jawnej składni, przekazując hash do naszej metody route get, gdzie kluczem jest defaults:, a wartością jest inny hash zawierający nazwę parametru, który chcemy przekazać do naszej akcji.

get 'popular', on: :collection, action: :index, defaults: { popular: true} 
  • trasa członkowska: możemy użyć on: member, aby określić, że nasza trasa pasuje do elementu kolekcji. Jeśli użyjemy tego, segment dynamiczny pojawi się jako :id. Helper URL zostanie również utworzony jako preview_post. Określając tę trasę za pomocą on: member, informujemy Rails, że jest to element tego konkretnego zasobu. Że nie jest to tylko kolejny zasób zagnieżdżony pod postami, ale ściślej powiązany lub powiązany z naszymi postami w tej aplikacji. Wiele tras członkowskich może być zdefiniowanych przy użyciu formatu bloku; ten format używa tej samej składni co format bloku do definiowania wielu tras kolekcji, wystarczy zastąpić collectionmember.

  • przekierowanie: jest jeszcze jedna koncepcja, o której można mówić w naszym przykładzie powyżej, a mianowicie przekierowanie. Rails daje nam możliwość przekierowania z jednej ścieżki do drugiej za pomocą redirect helper w połączeniu z trasą.get '/home', to: redirect('/'). Jeśli ktoś spróbuje uzyskać dostęp do ścieżki /home, zostanie natychmiast przekierowany do ścieżki głównej /. Oczywiście nie jest to ograniczone tylko do jednej ścieżki URL; możemy również mieć coś takiego: get '/home', to: redirect('/travel').

przegląd

trasy Rails stoją przed aplikacją. Trasa interpretuje przychodzące żądanie HTTP i:

  • dopasowuje żądanie do akcji kontrolera w oparciu o kombinację czasownika HTTP i wzorzec URL żądania
  • przechwytuje dane w adresie URL, które będą dostępne w params w akcjach kontrolera
  • Rails zachęca programistów do korzystania z wzorców Url RESTful podczas konfigurowania tras, z konceptualizacją manipulowania zasobami za pomocą czasowników HTTP.
  • możesz użyć makra resourcesdo bardzo szybkiego generowania tras RESTful.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.