Ostatnio szukając nowego rodzaju adresów url rozpracowałem bardziej w mechanizm który używamy w routes.rb. Problem jaki napotkałem polegał na przebudowie standardowego modeli adresów (domena.pl/kontroler/metoda/id) na inny bardziej odpowiadający potrzebom serwisu.
Już dość dawno temu dowiedziałem się od znajomych z #rubyonrails.pl, że jest możliwość użycia symbolu jako elementu adresu np:
map.connect ‘:par1/:par2′, :controller=>”test”, :action=>”first_test”
teraz wszystkie żądania przychodzące w postaci dwóch parametrów będą “lądować” w metodzie first_test.
Jeśli traktować adres jako element nawigacji serwisu, tzn na podstawie adresu widzimy, gdzie się w tym momencie znajdujemy np:
domena.pl/kategoria1/kategoria2
to występują dwa problemy:
1. Przy nie bardzo prostym serwisie otrzymujemy dużą ilość poziomów - 4 i więcej , co by przekładało się na dość długi i skomplikowany adres.
2. Przy listowaniu rekordów wchodzi w grę paginacja. Ja używałem dotychczas chyba najbardziej popularnego do tego pluginu jakim jest will_paginate. Jednak w tej sytuacji domyślnie dostajemy niezbyt ładny adres postaci:
domena.pl/kategoria1/kategoria2?page=11
Rozwiązaniem tych problemów byłoby rozbudowanie poszczególnych poziomów adresu, jak również wcielenie numeru strony z paginacji w naturalny sposób do adresu. Na podstawie domyślnych ustawień parametry adresu są rozdzielane przez:
1. /
2. .
3. ?
Elementu pierwszego już użyliśmy, drugi odpada ponieważ kojarzy się z rozszerzeniem (*.html, *.htm), natomiast trzeci wygląda za bardzo dynamicznie. Na podstawie analizy adresów url innych większych serwisów zauważyłem separowanie elementów adresu przez przecinki. Oczywiście w Ruby On Rails można to robić prosto z poziomu kontrolera i rozdzielania w nim poszczególnych elementów parametrów jakie przychodzą, jednak ta metoda wydaje się co najmniej mało błyskotliwa. Ponadto logika wskazuje, że rozdzielenie powinno się odbyć na poziomie rutingu aplikacji, zatem powinno być ustawione w pliku routes.rb. Jednak rozdzielenie postaci:
map.connect ‘:par1,:par2′, :controller=>”test”, :action=>”first_test”
nie działa. Rozwiązaniem problemów jest rozszerzenie separatorów o dodatkowe znaki:
module ActionController
module Routing
SEPARATORS = %w( / ; . , ? )
end
end
Wpis ten powinien nastąpić przed rysowaniem mapy adresów url (ActionController::Routing::Routes.draw) w routes.rb .Efektem tego jest możliwość rozszerzania ilości parametrów w adresie url nie tylko oddzielając je znakami / . ? ale również średnikami i przecinkami. Zatem teraz wpis:
map.connect “:kategoria1,podkategoria11/detal”, :controller => “show”, :action=>”detail”
jest w pełni zrozumiały przez aplikacji railsową. Ponadto paginację można zrealizować na przykład przez:
domena.pl/kategoria1/kategoria2,11
co robi niewątpliwie lepsze wrażenie niż wersja z pytajnikami.