2012-08-14 2 views
1

J'ai un contrôleur de session, avec: new,: create et: delete actions. J'ai aussi une méthode qui vérifie le contrôleur de la page courante:Empêche les rails de changer la partie contrôleur de l'url, en cas d'échec de la publication

def controller_for(path) 
    Rails.application.routes.recognize_path(path)[:controller] 
end 

Normalement, cette méthode fonctionne très bien, mais si l'utilisateur visite /login et les signes-vous avec les informations de connexion incorrectes, puis rails change l'URL pour /sessions et rend l'action :new, à quel point ma méthode jette au-dessus d'un ARROR

No route matches "/sessions" 

Il semble que recognize_path essaie de le faire:

>> r = Rails.application.routes 
>> r.recognize_path "/sessions" 
=> {:controller=>"sessions", :action=>"index"} 

Comme je n'ai pas d'action d'index, cela provoque une erreur. Ce que je veux vraiment, est la suivante:

>> r.recognize_path "/login" 
=> {:controller=>"sessions", :action=>"new"} 

Alors, comment puis-je forcer rails à garder l'URL comme /login en cas d'échec de la connexion, au lieu de changer à /sessions?

Répondre

2

Le problème est que vous utilisez des routes reposantes. Lorsque vous publiez le formulaire de connexion, vous créez une session, ce qui est réalisé en POSTing/sessions. Ceci est dirigé vers SessionsController#create./login est un chemin distinct, personnalisé, non reposant qui est envoyé à SessionsController#new, essentiellement un alias pour/sessions/new.

recognize_path par défaut interprète le chemin comme une requête GET lorsque l'environnement ne lui dit pas autrement. Et une requête GET suppose /sessions pour signifier l'affichage d'index.

# The recognize_path method in the Rails source: 
def recognize_path(path, environment = {}) 
    method = (environment[:method] || "GET").to_s.upcase 
    ... 
end 

Une manière de 'réparer' ceci est de changer votre routage. Par exemple, vous pouvez ajouter à vos itinéraires:

match "/process_login" => "sessions#create", :as => 'process_login' 

Et puis changer votre formulaire de connexion pour correspondre:

<% form_tag process_login_path do %> 
    [your login form here] 
<% end -%> 

Maintenant, vous posterai le formulaire/process_login au lieu de/sessions, et le chemin doit être interprété correctement par le système de reconnaissance.

+0

Merci, j'ai juste remarqué que quelqu'un avait répondu à cette question :) Bonne info là, je le comprends maintenant. – stephenmurdoch

+1

Heureux que c'était utile. Je perds aussi de temps en temps la trace de mes réponses Stack;) –

Questions connexes