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.

strange link_to behavior on links to controllers in modules

#183

This happens in the ERB template in the current edge as well as 2.0.2. This behavior is strange, and shouldn't happen...

First Invocation

<%=link_to('First Link', :controller => 'first/link')%>

# Generated HTML
# <a href="/first/link">First Link</a>

Successive Invocation (in the same ERB Template)

<%=link_to('Second Link', :controller => 'second') %>

# Generated HTML
# <a href="/first/second">Second Link</a>

There's a URL fragment stuck in the second URL which has been actually passed to link_to in the first invocation.

link_to shouldn't be working in this way...

Reported by Amol Hatwar (rubygem) · May 13th, 2008 @ 06:42 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Amol Hatwar (rubygem)
  2. Amol Hatwar (rubygem)
    Amol Hatwar (rubygem)

    Attached test patch that confirms the said behavior...

    May 13th, 2008 @ 09:18 PM

  3. Amol Hatwar (rubygem)
    Amol Hatwar (rubygem)

    If someone can confirm that this indeed is a *bug*, maybe I can work towards a patch that fixes it...

    May 18th, 2008 @ 05:42 AM

  4. nikz
    nikz
    • Tag set to helper

    Hey Amol,

    The relevant code is in /actionpack/lib/action_controller/routing.rb on line 348:

          # Returns a controller path for a new +controller+ based on a +previous+ controller path.
          # Handles 4 scenarios:
          #
          # * stay in the previous controller:
          #     controller_relative_to( nil, "groups/discussion" ) # => "groups/discussion"
          #
          # * stay in the previous namespace:
          #     controller_relative_to( "posts", "groups/discussion" ) # => "groups/posts"
          #
          # * forced move to the root namespace:
          #     controller_relative_to( "/posts", "groups/discussion" ) # => "posts"
          #
          # * previous namespace is root:
          #     controller_relative_to( "posts", "anything_with_no_slashes" ) # =>"posts"
          #
          def controller_relative_to(controller, previous)
            if controller.nil?           then previous
            elsif controller[0] == ?/    then controller[1..-1]
            elsif %r{^(.*)/} =~ previous then "#{$1}/#{controller}"
            else controller
            end
          end
        end
    

    From that, it looks the current behaviour is intended. Perhaps bring up a discussion on the mailing list?

    Also, just by the bye, your test fails for me, but not for the reason you describe. The first link_to call just generates "http://example.com", rather than a route at all. (That's on the latest edge rails).

    August 5th, 2008 @ 12:33 PM

  5. nikz
    nikz

    Actually, upon further investigation, that method isn't called anywhere! (nowhere I can grep for, anyways).

    Regardless, the REAL (slim shady) relevant section is in route_set.rb (line 322).

            # if the controller has changed, make sure it changes relative to the
            # current controller module, if any. In other words, if we're currently
            # on admin/get, and the new controller is 'set', the new controller
            # should really be admin/set.
            if !named_route && expire_on[:controller] && options[:controller] && options[:controller][0] != ?/
              old_parts = recall[:controller].split('/')
              new_parts = options[:controller].split('/')
              parts = old_parts[0..-(new_parts.length + 1)] + new_parts
              options[:controller] = parts.join('/')
            end
    

    Looks like the intended behaviour is what you're seeing :)

    Maybe someone can close this ticket?

    August 5th, 2008 @ 12:40 PM

  6. Pratik
    Pratik
    • State changed from new to invalid

    August 5th, 2008 @ 12:59 PM