Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

link_to_unless_current fails on restful routes

#3656

I've seen this reported elsewhere but a search of the tickets brought up nothing.

Basically link_to_unless_current seems to only look at the URL itself rather than comparing the URL and the METHOD which is important with restful routes. One annoying case I have is I use this to build my breadcrumbs. A breadcrumb is usually an 'index' method (/pages) so when I'm on the 'index' action for pages I just see the text. When I'm on the 'new' action for pages I see the link as a breadcrumb. But if I submit my form and it has an error and stays on the 'create' action and renders the 'new' view, the link disappears again because the 'create' and 'index' URL's are visually the same.

The solution would be to compare the current method with the intended method of the URL (which I assume would usually be GET but could be something else) along with the actual URL.

Any ideas on how to fix this? :)

Reported by Brendon · January 5th, 2010 @ 03:40 AM

State: stale
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Brendon
    Brendon
    • Tag changed from link_to link_to_unless_current restful routes to link_to, link_to_unless_current, restful, route

    January 5th, 2010 @ 03:41 AM

  2. Brendon
    Brendon

    I hacked this together quickly and it works for me. I've never submitted a patch or anything like that so I'm hoping this will do for now at least to promote discussion:

     @@@ def current_page?(options)
        url_string = CGI.unescapeHTML(url_for(options))
        request = @controller.request
    
        if options.is_a?(Hash)
          intended_method = options[:method].to_sym || :get
        else
          intended_method = :get
        end
    
        # 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
        else
          request_uri = request.request_uri.split('?').first
        end
        if url_string =~ /^\w+:\/\//
          url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" &&
          request.request_method == intended_method
        else
          url_string == request_uri &&
          request.request_method == intended_method
        end
      end @@@
    

    January 5th, 2010 @ 04:35 AM

  3. Brendon
    Brendon

    Ok, so I've had a further play and test and have come up with this code. link_to_unless_current needs to be modified to send through the html_options to current_page? so that it can then attempt to find a method from there. If anyone can help me to make the code more concise that's be helpful :) I'd also love to know if there's a way I can just override these two methods for my own purposes in a plugin if you conclude that this doesn't belong in the core.

    @@@module ActionView module Helpers #:nodoc:

    module UrlHelper
    
      def link_to_unless_current(name, options = {}, html_options = {}, &block)
        link_to_unless current_page?(options, html_options), name, options, html_options, &block
      end
    
      def current_page?(options, html_options)
        url_string = CGI.unescapeHTML(url_for(options))
        request = @controller.request
    
        if html_options.is_a?(Hash)
          intended_method = html_options[:method] || :get
        else
          intended_method = :get
        end
    
        # 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
        else
          request_uri = request.request_uri.split('?').first
        end
        if url_string =~ /^\w+:\/\//
          url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" &&
          request.request_method == intended_method.to_sym
        else
          url_string == request_uri &&
          request.request_method == intended_method.to_sym
        end
      end
    
    end
    

    end end@@@

    January 5th, 2010 @ 08:43 PM

  4. Rohit Arondekar
    Rohit Arondekar
    • State changed from new to stale
    • Importance changed from to Low

    Marking ticket as stale. If this is still an issue please leave a comment with suggested changes, creating a patch with tests, rebasing an existing patch or just confirming the issue on a latest release or master/branches.

    October 8th, 2010 @ 12:03 PM

  5. Brendon
    Brendon

    Thanks for following this up. I'm unable to check if this is an issue in master and won't be able to for some time. I suspect it'd still be a problem unless it's been specifically addressed in another ticket.

    October 29th, 2010 @ 04:31 AM