J'essaie d'implémenter un système d'url de vanité générique dans Rails 3. Générique dans le sens où l'url de vanité n'est pas lié à un modèle spécifique. Il est similaire à la gemme Vanities où j'ai un VanityUrlController
qui est touché à partir de toutes les urls de vanité. La différence est que je ne veux pas faire une redirection externe de foo.com/username
à foo.com/users/1
ou foo.com/product-name
à foo.com/products/1
. Je veux que l'url de vanity reste et que le VanityUrlContoller fasse une redirection interne qui imite l'action show correspondante.Redirections internes avec Rails 3
Je sais quel contrôleur et quelle action je veux envoyer la redirection interne, mais j'ai des problèmes avec l'envoi. C'est là où je suis en ce moment:
TargetController.new.process("show", request.env)
Il semble commencer à traiter la nouvelle « demande », mais il y a des éléments clés manquantes ... comme l'objet de la demande réelle.
Toutes les pensées ou les pointeurs seraient très appréciés.
Mise à jour:
Je courais à travers la méthode d'expédition en ActionController qui me semble être un peu plus loin.
TargetController.new.dispatch("show", request)
J'ai deux problèmes, 1) il est répertorié comme une méthode api privée donc s'il y a une autre façon de faire, je préfère que, et 2), même si elle est rendu le spectacle modèle pour le TargetController, il se plaint de "Missing template vanity_urls/show."
MISE À JOUR
Voici les bases de la solution que nous sommes arrivés avec. Nous faisons d'autres choses comme forcer les encodages et vérifier d'autres choses spécifiques à l'application, mais cela devrait être tout ce dont vous avez besoin pour démarrer.
Cela se trouve tout en bas de votre fichier routes.rb
afin que vos routes de vanité ne pas entailler vos autres routes nommées.
# Vanity routes.
match ':id', :as => 'vanity', :to => proc { |env|
id = env["action_dispatch.request.path_parameters"][:id]
vain_object = <method to find the object you want to display>
if vain_object.nil?
# render your 404 page
'application#404'
else
model = vain_object.class.model_name
# figure out the controller you want to go to
controller = [model.pluralize.camelize,"Controller"].join.constantize
# reset the :id parameter with the id of the object to be displayed
env["action_dispatch.request.path_parameters"][:id] = vain_object.id
# do your internal redirect
controller.action("show").call(env)
end
}
Vous devez également faire attention lors de la création de vos itinéraires de transition afin qu'ils n'entrent pas en collision avec vos autres contrôleurs. D'autres choses utiles à savoir sur sont:
Rails.application.routes.routes.any? { |r| r.requirements[:controller] == vanity_url }
qui vous indique si votre vanity_url
a le même nom que un contrôleur de courant.
Rails.application.routes.recognize_path("/#{vanity_url}", :method => :get)
Ce qui vous indique si cela correspond déjà à quelque chose.
Bien sûr, il y a un couple de hacks le long du chemin, mais ça fonctionne comme un charme.
Voici une option similaire avec le lambda extrait et les contraintes appliquées http://stackoverflow.com/questions/5641786/testing-rack-routing-using-rspec – Agustin