Routovani v Ruby on Rails I – routes.rb
Routování v Ruby on Rails funguje jako obousměrný proces. Dokáže vytvářet url adresy podle vytvořených pravidel a zpětně dokáže tyto adresy převést na sprváné volání controllerů a akcí.
V praxi si tohle můžeme představit následovně. Máme například adresu:
1 |
/user/zaachi |
Routing engine se postará o to, že najde správný controller a správnou akci, podle tvaru url adresy, kam bude tento požadavek směrovat, a které bude volat.
V opačném případě bude funkce obdobná. Při volání url adresy:
1 |
<%= link_to @user.name, user_path(@user.name) %> |
bude vykládána správná adresa
Routes.rb
Soubor routes.rb slouží pro definování všech cest a adres (tras), které chcete v aplikaci používat.
Tyto adresy jsou uvedeny jako blok ActionController::Routing::Routes.draw.
Blok je aplikací zpracováván odshora směrem dolů a jednotlivé routy jsou poté používány v aplikaci.
Pokud jsou routy níže předefinovány, jsou aplikací přepsány.
Routes.rb může obsahovat několik druh rout:
- Named Routes
- Regular Routes
- Default Routes
- RESTful Routes
- Nested Routes
V tomto, prvním, článku se podíváme na první dva typy rout. :
Named Routes
Jedná se o přímo pojmenované trasy, kdy si vytvoříme jak celou adresu pro použítí, tak přímo nadefinujeme, který kontroler a která akce se bude po zadání dané adresy volat.
Vytvoříme si například routu, která bude odkazovat na mapu webu:
1 |
map.sitemap '/sitemap', :controller => 'sitemap', :action => 'generate' |
Adresu potom můžeme jednoduše vyskládat například takto:
1 2 |
puts sitemap_url puts sitemap_path |
Po jejím zavolání se bude odkazovat přímo na sitemap_controller.rb ve kterém se zpracuje akce generate.
Regular Routes
Regular routes jsou podobné RestFul routám (na ty se podíváme příště), vlastně bych mohl říct, že se jedná o kombinaci RESTful rout a Named rout.
Umožňují nadefinovat si adresu, do které můžeme opět přímo nadefinovat volaný kontroler a akci, ovšem oproti Named routám navíc může adresa přebírat další parametry, které jsou dále zpracovávány a předávány.
Většina techto rout je možné nahradit RESTful routami, Regular routes spíše předefinovávají některé části RESTful rout.
Nejlepší bude uvést jednoduchý příklad:
1 |
map.userdetail 'user/:username', :controller => 'user', :action => 'show' |
Při volání se použije kontroler user_controller a volá se akce show, navíc je vytvořen parametr se jménem username. Na tento parametr musíme myslet i při volání:
1 2 |
puts userdetail_path(:username => @user.nick) puts userdetail_url(:username => @user.nick) |
Výchozí hodnoty
Do rout můžeme krom volaného kontroleru a akce nadefinovat výchozí hodnoty, které se budou předávat jako parametry. Tyto parametry budou poté obsaženy v poli params:
1 2 3 4 |
map.userdetail 'user/:username/man', :controller => 'user', :action => 'show', :defaults => { :type => 'man' } |
Po přístupu na tuto adresu se opět volá user_controller a metoda show, do které je předán jako parametr hodnota params[:username], ale krom tohoto parametru je předán automaticky ještě jeden parametr a to params[:type], který obsahuje hodnotu “man”.
Požadavky na parametry
Pro lepší rozhodnování směrování existuje možnost nadefinovat si v routách podmínku pro každý parametr. Tyto podmínky jsou uvozeny klíčem :requirements, který obsahuje pole podmínek:
1 2 3 4 |
map.userdetail 'user/:username/man', :controller => 'user', :action => 'show', :requirements => { :username => /[A-Z]d{10}/ } |
V podmínce je přesně stanoveno, jaké hodnoty může proměnná obsahovat, a dle těchto podmínek se určí správný kontroler a akce. Podobné routy se tak mohou lišit jenom v různých podmínkách.
Podmínky v routách
Podobně jako požadavky na parametry, můžeme vytvořit podmínky pro celou routu. V současné době je podporována pouze podmínka :method , která rozhoduje o metodě přístupu:
1 2 3 4 |
map.userdetail 'user/update/:username', :controller => 'user', :action => 'update', :conditions => { :method => 'post' } |
Globbing
Globbing vytváří jakousi univerzální routu na základě určitěho požadavku. Nejlépe to bude vysvětleno zase na příkladu:
1 |
map.connect 'user/*other', :controller => 'user', :action => 'runall', |
Nyní máme nadefinovanou trasu, která začíná řetězcem user/, ale může obsahovat libovolný počet dalších parametrů. Tyto parametry jsou přebrány a předány do params pole. Pokud například zadáme adresu /user/edit/zaachi/ budou všechny tyto parametry v poli params[:other]
Route with_options
Pokud máme několik podobných rout, které se liší jenom nepatrně, můžeme použít with_options, který shlukuje všechny podobné možnosti více rout:
1 2 3 4 |
map.with_options :controller => 'user' do |user| user.list ':username/show', :action => 'show' user.delete ':username/edit', :action => 'edit' end |
Tímt si ušetříme zbytečné rozepisování jednotlivých rout, a můžeme jednoduše nadefinovat pro jeden kontroler více akcí pod různými trasami.
Default routes
Default routs jsou jakési výchozí trasy, které jsou použity v případě, že aplikace nenašla vhodnou routu, která by jí vyhovovala. Po vytvoření nového projektu většinou soubor routes.rb přímo některé defaultní routy obsahuje. Taková routa může vypada například takto:
1 2 |
map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' |
Jsou uvedeny až na konci seznamu rout, aby byly zpracovány v případě že nebyla nalezena jiná routa.
Závěrem
Routování je důležitá součást vývoje v RoR. V dalším článku se podíváme především na RESTful routy, které jsou v RoR aplikacích asi nejpoužívanější.