Mam trochę inną adresację niż /controller/action, w związku z tym pytanie, jak (jakim mechanizmem) zrealizować budowanie adresów do moich zasobów na stronie?
Na kilku różnych odsłonach będzie jakaś lista elementów biżuterii, biżuteria zawsze pokazywana będzie na odsłonach /bizuteria/jakas-nazwa-bizuterii/id
Gdzie umieścić metodę do budowania takiego adresu dla elementów biżuterii? (składającą “/bizuteria/” i create_url(nazwa) i “/” i bizuteria.id w calosc), żeby potem porządnie z tego korzystać i nie sklejać tego za każdym razem?
Musisz sporo o railsowym routingu poczytać – masz Obiego “The Rails Way”? Tam to całkiem nieźle jest wyjaśnione.
Jeśli jakas-nazwa-bizuterii przekłada się zawsze na jakąś akcję lub kontroler (lub nawet id), to /bizuteria powinna być namespace’em ścieżek branych pod uwagę. To tak na wstępie. “rails namespaced routes”. Potem “rails named routes”. Potem powinno już być z górki 
Dzięki.
jakas-nazwa-bizuterii nie przekłada się na żadną akcje, ani kontroler, jest w adresie ze względów SEO, /controller/trash-trash-trash/id -> :controller => jewlery :action => view :id => id
Pytanie o miejsce umieszczenia metody do generowania lisnku do odsłony elementu biżuterii pozostaje aktualne…
@zmaliszewska:
Użyj named_route, np:
config/routes.rb
map.show_jewel '/bizuteria/:slug/:id', :controller => 'jewlery', :action => 'view'
Powinno być “jewellery” a nie “jewlery” tak BTW.
model Jewel (przykład), potrzebujesz metody slug która wygeneruje słowa kluczowe na potrzeby SEO:
[code=ruby]class Jewel < ActiveRecord::Base
def slug
self.name.gsub(/[^[:alnum:]]/,’-’) # zamien wszysktkie znaki z name ktore nie sa alfanumeryczna na -
end
end[/code]
generowanie linka, zakladajac, że @jewel to obiekt modelu AR.
<%= link_to @jewel.name, show_jewel_path(@jewel.slug, @jewel.id) -%>
Dziękuje pięknie! Dokładnie o to mi chodziło
A “model AR” to???
show_jewel_path - nazwa tej metody powstaje na podstawie definicji z routes.rb?
A co do mojego ‘jewlery’ to rzeczywiście była literówka, bo używam ‘jewelry’ a ‘jewellery’ jest brytyjskie - ale to już tematy na inne forum! Dzięki jeszcze raz, zabieram się za implementację.
AR = ActiveRecord - mówiąc prościej: jak coś wyciągasz z bazy, to jest to obiekt AR (poza kilkoma przypadkami, ale żeby nie mieszać w głowie, to pozostańmy, że zawsze jest to obiekt ar)
Dzięki, a jeszcze jedno pytanie do tego wątku:
Poprzednio działało mi (id było jakoś odczytywane z ?id=):
map.connect "bizuteria/:name.html", :controller => 'jewelry', :action => 'show'
A teraz z html nie działa:
map.show_jewelry "bizuteria/:slug.html?id=:id", :controller => 'jewelry', :action => 'show'
Komunikatu błędu: undefined method `has_key?’ for 1:Fixnum - nie rozumiem.
jeśli jakaś zmienna nie jest podana we wzorcu, jest dodawana po ?
map.connect "bizuteria/:name.html", :controller => 'jewelry', :action => 'show'
masz podaną zmienną :name, ale nie masz :id -więc :id będzie występował jako ?id=cos
map.show_jewelry "bizuteria/:slug.html?id=:id", :controller => 'jewelry', :action => 'show'
zamień na:
map.show_jewelry "bizuteria/:slug.html", :controller => 'jewelry', :action => 'show'
i przekazuj normalnie id, wtedy otrzymasz link w postaci bizuteria/costam.html?id=cos
choc nie wiem ,czy ladniej by nie wygladalo:
map.show_jewelry "bizuteria/:id-:slug.html", :controller => 'jewelry', :action => 'show'
wtedy otrzymasz linka w postaci:
bizuteria/identyfikator-opis_do_seo.html
Niestety 
Teraz działa mi http://www.example.com/bizuteria/lancuszek-zloty-serce/44.html
map.show_jewelry "bizuteria/:slug/:id.html", :controller => 'jewelry', :action => 'show'
i buduję w różnych miejscach automatycznie linki za pomocą:
<%= link_to jewelry.name, show_jewelry_path(jewelry.url_name, jewelry.id) -%>
Jednak dla przykładów które podałeś, dostaję błąd: undefined method `has_key?’ for 1:Fixnum dla drugiego argumentu show_jewelry_path z powyższego kodu (1 z tego błędu to pierwsze id pobrane z bazy). Co do samej budowy adresu zgadzam się, rozwiązanie które zaproponowałeś jest lepsze
Jednak czemu dostaję taki błąd?
Co najdziwniejsze, adres /bizuteria/4-a-tu-jej-jakis-opis-seo.html działa dla reguły:
map.show_jewelry "bizuteria/:id.html", :controller => 'jewelry', :action => 'show'
Jednak wtedy też przy budowaniu adresów opisanym wyżej dostaję ten sam błąd
Czy ktoś wie czemu?
Jakiej wersji Rails używasz ? Pod 2.3.2 ostatni przykład podany przez Ciebie generuje u mnie poprawnie url’a:
http://localhost:3000/bizuteria/jakis-tekst/1.html
Rails 2.3.2 - i masz rację ten przykład generuje poprawnie urla, dopiero po zmianie reguł w routes (na takie jak w moim przykładzie) pojawia się problem z generacją url’a.
Tzn, wszystko co opisałeś w swojej odpowiedzi wyżej działa jak trzeba, ale chcę zmienić jeszcze adresację na: /bizuteria/id-jakas-nazwa.html (zamiast /bizuteria/costam-costam/id.html) - i wtedy wywala się metoda do tworzenia urla.
map.show_jewelry "bizuteria/:id-:slug.html", :controller => 'jewelry', :action => 'show
Przy generowaniu url’a podaj najpierw id a pozniej slug, czyli:
link_to “test”, show_jewelry_path(1, ‘test’)
Musi działać 
Prawie jesteśy w domu już, ale jeszcez coś jest nie tak.
dla: link_to “test”, show_jewelry_path(1, jewelry.url_name) dostaję: undefined method `has_key?’ for “Zloty-Lancuszek”:String ()
adres: /bizuteria/3-:slug.html - pokazuje biżuterię o id 3 - tak jak trzeba
adres: /bizuteria/3-byleco.html - No route matches “/bizuteria/3-byleco.html” with {:method=>:get}
Czyli jest problem z :slug w definicjach routes.rb - jakiś pomysł?
Rozwiązanie pierwsze:
map.show_jewelry "bizuteria/:id-:slug.html", :controller => 'jewelry', :action => 'show', :requirements => {:id => /\d+/}
Rozwiązanie drugie:
[code=Ruby]# w config/routes.rb
map.resources :jewelry
w app/models/jewlery.rb:
def to_param
“#{id}-#{url_title}”
end[/code]
I wtedy tworzymy linki normalnie przez
[code=Ruby]@jewlery = Jewlery.first # whatever…
…
link_to “test”, jewelry_path(@jewelry, :html) #=> /bizuteria/1-costam.html[/code]
Opis metody to_param.
Drugie rozwiązanie mi działa jeżeli dodam regułę:
map.show_jewelry "bizuteria/:id.html", :controller => 'jewelries', :action => 'show'
Bez tego buduje mi ścieżkę z /jewelries/5-nazwa.html - a potrzebuję polskiej nazwy tutaj. Tak czy inaczej to krok do przodu, dzięki 
Możesz też dodać parametr :as do nazwy zasobu w pliku config/routes.rb:
map.resources :jewelry, :as => "bizuteria"
Wtedy ścieżki będą miały postać “bizuteria/5-costam.html”
Polecam przeczytanie dokumentacji metody resources.