Ammesso che i valori di keyword e title non ti servano, esistano cio
solo
per comporre la URL, il mio consiglio di evitare di sporcare il file di
routing.
Puoi benissimo sovrascrivere il metodo ActiveRecord::Base#to_param e
fargli
ritornare il path che serve a te.
Ad esempio
class Guide < ActiveRecord::Base
def to_param
if persisted?
"#{id}/#{subcategory.name.parameterize}/#{title.parameterize}"
else
super
end
end
end
A quel punto ti baster passare
software_url(:id => guide.to_param)
dopo aver cambiato la regola di routing in
map.software ':id', :controller => 'view', :action => 'programma'
Nota che l’uso di / nella generazione di path potrebbe andare in
conflitto
con le impostazioni di default di routing di Rails. Motivo per cui in
genere
si consiglia l’uso di -.
Vedi questo screencast
In tal caso puoi passare un diverso requirement al parametro :id nella
route.
map.software ':id', ... , :id => /.*/
Personalmente lo sconsiglio poich potrebbe andare in conflitto con altri
sistemi.
Altra cosa. Preferisci sempre l’uso delle risorse. In questo caso non c’
motivo per cui tu non le debba scegliere.
map.resources :software
software_path(guide)
Il vantaggio che se usi le convenzioni, Rails funziona molto meglio.
Altro consilio. Evita catene di metodi come
“guide.title.split.join(”-“).downcase” poich la possibilit che generino
bug direttamente proporzionale al numero di metodi che hai in catena.
Un
codice cos poi molto complesso da testare e questo mi lascia pensare
che
tu non abbia creato un test che validi il costrutto. Al posto, crea un
metodo nella class Guide.
In questo caso, puoi rimpiazzare il “split.join(”-“).downcase” con un
nice
#parameterize offerto da Rails senza bisogno di un metodo aggiuntivo. In
linea di massima, evita elaborazioni molto complesse on-the-fly quando
chiami altri metodo, altrimenti se dovrai generare quel path altrove
dovrai
duplicare la logica di esecuzione.
Dulcis in fundo, arriviamo al punto fondamentale. Per impedire la
duplicazione delle route il consiglio che ti d di eseguire una verifica
nel controller. In teoria la puoi eseguire anche ora, ma il motivo per
cui
ho sottolienato l’uso di #to_param e delle risose perch la rende molto
pi semplice.
Il controllo si basa sul verificare che l’URL chiamato sia quello che
normalmente la pagina comporrebbe, in alternativa reindirizzare a quello
corretto impostando un 301. Ecco un esempio (d per assunto che #show sia
la
action che mostra il programma, che nel tuo caso si chiama programma.
Personalmente sconsiglio nel modo pi assoluto di mischiare italiano con
inglese, soprattutto in Rails)
class GuidesController
before_filter :find_guide, :only => %( show )
before_filter :validate_url, :only => %( show )
def show
# ...
end
private
def find_guide
# Importante: nel caso tu adotti una struttura dove
# il parametro :id "sporcato" da altri valori, assicurati
# che il find avvenga correttamente.
@guide = Guide.find(params[:id])
end
def validate_url
if request.request_uri != guide_path(@guide)
# rigenero il path utilizzando url poich i redirect
# dovrebbero per RFC contenere sempre URI assoluti
redirect_to guide_url(@guide), :status => 301
end
end
end
Il codice un prototype. L’ho scritto al volo senza test e senza la
versione di Rails (ad esempio Rails 3 mi pare abbia deprecato
request.request_uri) quindi perdona eventuali errori. Ad ogni modo,
dovrebbe
darti diversi spunti di approfondimento.
–
Simone C.
Application Developer
Site & Blog: http://www.simonecarletti.com
Email: [email protected]
LinkedIn: http://linkedin.com/in/weppos
Skype: weppos