Rails 5 Routing Cookbook:

Měli byste mít na paměti, že Rails je názorově vyhraněný framework a jedním z jeho základních principů je přednost konvencí před konfigurací. To znamená, že pokud k tomu nemáte velmi dobrý důvod, neměli byste porušovat žádný z výše uvedených vzorů a konvencí pojmenování.

Pokud bych se například rozhodl kódovat akci index jako get 'cars/index' nebo akci create jako post 'car/create', porušilo by to out-of-the-box chování Rails pro pomocné metody, jako jsou form_for, link_to a redirect_to.

Důsledkem porušování konvencí bez záměru je chaos a vzniká zamotaný nepořádek, kvůli kterému budete s frameworkem bojovat celé hodiny.

Foto: Daniele Levis Pelusi na Unsplash

Singulární trasy zdrojů

Možné je také mít trasy pro singulární zdroje, tj. zdroje, které lze vyhledat bez uvedení :id, například ty, které se vztahují k current_user nebo current_account. Toho lze dosáhnout pomocí integrovaných singulárních zdrojů systému Rails.

resource :profile 

Vložené trasy

Někdy potřebujeme vnořit zdroje uvnitř jiných zdrojů. Pokud například chci vytvořit rezervaci pro konkrétní auto v garáži, může být výhodnější chytit :idpro toto auto z adresy URL než ze skrytého pole formuláře, se kterým by mohl zlomyslný uživatel manipulovat. Způsob, jakým vytváříme vnořené prostředky v systému rails, je následující:

resources :cars do 
resources :bookings
end

Tím se vytvoří všech sedm akcí CRUD pro rezervace vnořené do aut. Obvykle však všech sedm cest nepotřebujete. A i když je potřebujete, rozhodně nemusí být všechny vnořené. Řekněme, že to, co potřebujeme, je akce pro vytvoření rezervace (budeme předpokládat, že formulář pro vytvoření rezervace sídlí v akci show vozu) a pro úpravu a aktualizaci existující rezervace. Potřebuji k úpravě/aktualizaci rezervace znát :idvůz? Odpověď je samozřejmě ne. Proto chci, aby moje aplikace reagovala na následující adresy URL:

# to CREATE a booking
POST request to http://my-ruby-garage.com/cars/:id/bookings/create# to EDIT a booking
GET request to http://my-ruby-garage.com/bookings/:id/edit# to UPDATE a booking
PATCH request to http://my-ruby-garage.com/bookings/:id/

Které generuje následující kód:

resources :cars do 
resources :bookings, only:
end
resources :bookings, only:

Rails nám umožňuje upravit, která ze standardních tras CRUD má být generována, zadáním pole symbolů nebo jediného symbolu do volby :only nebo jejího opaku :except.

Non-CRUD Routes

Nejsme omezeni na sedm tras zdrojů CRUD. Můžeme také zadat trasy, které se vztahují k jednomu prostředku (členské trasy) nebo k několika prostředkům (trasy kolekcí).

Členské trasy

Pokračujeme-li v našem příkladu s garáží RubyGarage, lze do ní zaparkovat auta nebo je z ní vyjmout. Představme si, že máme akce řadiče, které jsou schopny provádět tyto akce, které mění nějaký atribut konkrétního auta.

resources :cars do 
member do
patch :park
patch :remove
end
end

Výše uvedené nám umožňuje posílat požadavky na opravu na http://my-ruby-garage.com/cars/:id/park a http://my-ruby-garage.com/cars/:id/remove a najít konkrétní auto v řadiči před příslušnou úpravou zdroje.

Sběrné trasy

Stejně tak někdy chceme provést nějakou akci na několika zdrojích najednou. Například možná potřebujeme zaparkovat a odstranit kolekci aut najednou. Můžeme použít následující kód:

resources :cars do 
collection do
post :park, as: :bulk_park
post :remove, as: :bulk_remove
end
end

Tady nastavíme naši aplikaci tak, aby reagovala na http://my-ruby-garage.com/cars/park a http://my-ruby-garage.com/cars/remove, respektive tyto akce pojmenujeme bulk_park a bulk_remove. Nezapomeňte, že ke generování cest URL uvnitř naší aplikace můžeme použít pojmenované cesty. Pro vytvoření odkazu na cestu k zaparkování sbírky aut bychom mohli použít:

<%= link_to "Park Cars", bulk_park_path, method: :post, class: "button" %>

Jmenné cesty

Jmenné cesty prefixují cestu URL zdrojů uvnitř bloku jmenného prostoru a pokusí se najít příslušné řadiče pod modulem se stejným názvem jako jmenný prostor. Typickým použitím tohoto vzoru jsou jmenné prostory administrátorů a jmenné prostory api.

namespace :factory do 
resources :cars
end

Tento příklad vytvoří následující trasy:

Prefix Verb URI Pattern Controller#Action factory_cars GET /factory/cars(.:format) factory/cars#index
POST /factory/cars(.:format) factory/cars#create factory_car GET /factory/cars/:id(.:format) factory/cars#show
PATCH /factory/cars/:id(.:format) factory/cars#update
PUT /factory/cars/:id(.:format) factory/cars#update
DELETE /factory/cars/:id(.:format) factory/cars#destroy

A řadič by musel být také se jmenným prostorem :

class Factory::CarsController < ApplicationController
# ...
end

Scoped Routes

Metoda scope nám umožňuje zůstat DRY a sdružovat související pravidla směrování. Při použití bez voleb je podobná metodě namespace, ale příslušné kontroléry nemusí mít jmenný rozsah modulu.

scope :factory do 
resources :cars
end

Generuje následující trasy:

Prefix Verb URI Pattern Controller#Action factory_cars GET /factory/cars(.:format) cars#index
POST /factory/cars(.:format) cars#create factory_car GET /factory/cars/:id(.:format) cars#show
PATCH /factory/cars/:id(.:format) cars#update
PUT /factory/cars/:id(.:format) cars#update
DELETE /factory/cars/:id(.:format) cars#destroy

Scope podporuje tři volby: module, path a as.

Řekněme, že máme vícekrokového průvodce vytvořením nového vozu v továrně, který je obsluhován kontrolérem žijícím v modulu průvodce. Chceme, aby se cesta v prohlížeči zobrazovala jako http://my-ruby-garage.com/create-a-car a aby bylo možné na tuto cestu odkazovat uvnitř naší aplikace jako create_car. Existuje modul Wizard::Car, který zná jednotlivé kroky průvodce:

scope module: 'wizards', path: 'create-a-car', as: 'create_car' do
Wizard::Car::STEPS.each do |step|
get step, to: "cars##{step}"
end
post :validate-step, to: 'cars#validate_step'
end

Výše uvedený kód vytvoří pro každý krok stejný vzor. Například krok1 je v prohlížeči dostupný prostřednictvím adresy URL http://my-ruby-garage.com/create-a-car/step1, jemu odpovídající formulář odešle požadavek na http://my-ruby-garage.com/create-a-car/validate-step a cestu lze vyvolat voláním create_car_step1_path.

Přesměrování trasy

Rails nám také umožňuje provádět přesměrování přímo v routes.rb. V předchozím příkladu třeba chci, aby každý, kdo přistane na http://my-ruby-garage.com/create-a-car, byl automaticky přesměrován na první krok. Toho lze dosáhnout pomocí následujícího kódu:

get 'create-a-car', 
to: redirect("/create-a-car/#{Wizard::SpotAccount::STEPS.first}")

Vypnutelné parametry trasy

Vypnutelné parametry trasy můžete definovat předáním hashe pro volbu :defaults.

resources :cars do
collection do
get :export, defaults: { format: 'csv' }
end
end

Pomocí tohoto kódu návštěva http://my-ruby-garage.com/cars/export zavolá akci exportu v kontroléru cars a odpovídající akce kontroléru bude ve výchozím nastavení odpovídat pomocí csv.

Route Globbing

Pomocí segmentů se zástupnými znaky (fragmenty s předponou hvězdička) můžeme určit, že zbývající části trasy mají odpovídat určitému parametru. Tomuto postupu se říká route globbing.

get '/rent/*slugs', to: 'cars#index', as: :rent_cars

Tato trasa by odpovídala http://my-ruby-garage.com/rent/lisbon/suv-sedan a nastavila by parametry na „lisbon/suv-sedan“. To by pak mohlo být použito v systému vyhledávání nebo filtrování proti naší databázi k nalezení aut v Lisabonu typu suv nebo sedan.

Píšu gem Slugcatcher s ohledem na tuto funkcionalitu, aby bylo možné označit modely Rails, které lze vyhledat jako route slugs.

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.