2011-02-14 5 views
10

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.

+0

Voici une option similaire avec le lambda extrait et les contraintes appliquées http://stackoverflow.com/questions/5641786/testing-rack-routing-using-rspec – Agustin

Répondre