2009-07-09 10 views
1

Est-ce que quelqu'un sait comment empêcher le mécanisme défaillant de link_to_unless_current?link_to_unless_current échoue lors du traitement de formulaires contenant des messages d'erreur avec des routes restfull

f.e .: J'ai ma navigation avec

link_to_unless_current "new task", new_task_path 

Lorsque je clique sur le lien, je viens à la nouvelle forme de chemin taks ... Et aucun lien est créé -> ok. Ensuite, je mets des valeurs incorrectes dans le formulaire et soumettre. Le TasksController traite l'action "create", la validation du modèle ActiveRecord échoue en raison des données incorrectes et le contrôleur rend la "nouvelle" action (et inclut les messages d'erreur pour le modèle).

class TasksController < ApplicationController 
    def create 
     @task = Task.new(params[:task]) 

     if @task.save 
      flash[:notice] = 'task was successfully created.' 
      redirect_to(tasks_url) 
      else 
      render :action => "new" 
     end 
    end 
end 

Mais ici le lien est créé! -> En raison de la différence entre les urls:

link path = new_task_path 

mais

posted path = tasks_path with :method => :post 

Quelqu'un sait comment résoudre ce problème proprement?

Merci

Répondre

2

Avoir un rapide coup d'oeil à la source pour link_to_unless_current ...

... il utilise current_path? de sorte que vous devriez être capable de faire quelque chose comme ceci:

Dans une aide ...

def current_page_in?(*pages) 
    pages.select {|page| current_page?(page)}.compact.any? 
end 

... et alors, selon vous, vous pouvez simplement fournir un tableau de named_routes ou de hachages comme la réponse de Shadwell ci-dessus.

<%= link_to_unless(current_page_in?(new_thing_path, things_path), "add a thing") %> 

Vous avez l'idée ...

À JOUR

avait une réflexion à ce sujet ... et ce serait génial si vous pouviez simplement l'utiliser comme vous espériez que le méthode originale travaillée. Ici, nous comparons la route nommée fournie (ou le contrôleur + hash d'action) avec la page en cours ET son référent.

def current_page_or_referrer_in(options) 
    url_string = CGI.unescapeHTML(url_for(options)) 
    request = @controller.request 
    # We ignore any extra parameters in the request_uri if the 
    # submitted url doesn't have any either. This lets the function 
    # work with things like ?order=asc 
    if url_string.index("?") 
    request_uri = request.request_uri 
    referrer_uri = request.referrer 
    else 
    request_uri = request.request_uri.split('?').first 
    referrer_uri = request.referrer.split('?').first 
    end 

    #referrer_uri always has full path (protocol, host, port) so we need to be sure to compare apples w apples 
    if url_string =~ /^\w+:\/\// 
    ["#{request.protocol}#{request.host_with_port}#{request_uri}", referrer_uri].include?(url_string) 
    else 
    referrer_uri = referrer_uri.gsub(request.protocol, '').gsub(request.host_with_port, '') 
    [request_uri, referrer_uri].include?(url_string) 
    end 
end 

La beauté est qu'il vous permet de le faire maintenant ce (à partir de votre exemple):

<%= link_to_unless(current_page_or_referrer_in(new_task_path), "Add a task") %> 

Il va alors afficher si vous êtes sur new_task_path ou une page à laquelle il a été envoyé (comme la page de création

+0

Cool cool cool thanks – Lichtamberg

+0

Presque comme une bonne réponse!Mais le problème se passe maintenant de l'autre côté: J'ai à la fois le nouveau lien et la liste (c'est-à-dire l'index) placés dans la barre de navigation gauche, ce qui me donne un aperçu de l'action dans laquelle je suis. impossible de trouver le vrai lien actif qu'il devrait mettre en évidence (c.-à-d. nouveau) car l'URL de publication signifie que le lien d'index serait également mis en évidence. Vraiment moche dans cette partie .... –

0

Vous pouvez le faire avec au lieu de link_to_unless_current:

link_to_unless(controller_name == 'tasks' && 
       (action_name == 'new' || action_name == 'create'), 
       new_task_path) 
+0

Lol ... facile facile facile gg – Lichtamberg

+0

Mais n'y a-t-il pas une solution qui fonctionne avec les routes nommées? – Lichtamberg

Questions connexes