2009-12-03 7 views
3

Nous avons donc un système hérité qui suit les endroits avec des ID comme "Europe/France/Paris", et je construis une façade Rails pour en faire des URLs comme http: // foobar/places/Europe/France/Paris. Cette exigence n'est pas négociable, le nombre de niveaux possibles en illimité, et nous ne pouvons pas échapper aux barres obliques.Ruby on Rails: Routage pour une arborescence de lieux

Mise en place routes.rb pour http://foobar/places/Europe est trivial:

map.resources :places 

... mais http: // foobar/lieux/Europe/France se plaint "Aucune action a répondu à l'Europe". J'ai essayé:

map.connect '/places/:id', :controller => 'places', :action => 'show' 

... mais cela donne le même résultat, car apparemment le: id se termine au premier '/'. Comment puis-je faire en sorte que l'ID couvre tout et n'importe quoi après les "lieux"?

Répondre

6

Jetez un oeil au Guide de routage pour une documentation complète:

http://guides.rubyonrails.org/routing.html

section Plus précisément "4.9 Route englobement".

Mais je pense que ce que vous voulez vraiment faire est de déclarer votre itinéraire comme:

map.connect '/places/*id', :controller => 'places', :action => 'index' 

Appelé avec une URL comme

/places/foo/bar/1 

Yields a params[:id] => ["foo", "bar", "1"] 

que vous pourriez facilement (re) joindre à «/» pour obtenir la chaîne complète que vous voulez « foo/bar/1 » (vous devrez probablement re-insérer le slash manuellement.

Cela devrait vous aller.

+0

Brillant, ça marche presque! Le seul problème est que le contenu est maintenant rendu en HTML, même si j'essaye de le forcer avec un suffixe ".xml"? J'utilise la norme respond_to do | format | bloc. – jpatokal

+0

Il ressemble à la globbing de route avec: le support de format est un problème connu - c'est, cela ne fonctionne pas, comme vous l'avez découvert. Le bug/patch est ici discuté ici: http://bit.ly/5LICLH mais il semble que ce ne soit pas dans la version actuelle de Rails. Puisque vous n'avez aucun contrôle sur la partie URL (la route), le mieux que je puisse penser est d'ajouter un paramètre de chaîne de requête (? Format = xml ou? Format = json) que vous pouvez détecter dans votre contrôleur et agir en conséquence. Sinon, on dirait que vous êtes SOL –

0

J'ai modifié la réponse de Cody légèrement au-dessus de trouver ceci:

map.place '/places/*id', :controller => 'places', :action => 'show' 
map.connect '/places/*id.:format', :controller => 'places', :action => 'show' 

En utilisant map.place au lieu de map.connect, Rails sait ce que les ressources que nous avons affaire et généré place_url, place_path aides etc correctement .

Maintenant, la 2ème ligne devrait travaux, mais pas grâce au bug ci-dessus, voici donc une solution de contournement pour places_controller.rb qui divise manuellement l'ID et définit le format, par défaut XML:

id, suffix = params[:id].join('/').split('.') 
params[:format] = suffix ? suffix : "xml" 
+0

Nice touch sur simplement saisir le format du dernier composant de chemin. Cela devrait faire l'affaire! –

+1

Il m'est apparu un peu plus tard que l'identifiant peut aussi contenir des points, donc utiliser .split (/ \. (Html ​​| xml) $ /) est un peu plus sûr. – jpatokal