#6432: Polymorphic URLs for nested resources

I've reopened ticket #6432, which patched simply_helpful to allow
polymorphic URL generation for nested resources.

Since simply_helpful has been merged into core, I rewrote the patch
for ActionPack. It implements the following usage:

# Routes.rb
map.resources :workshops do |w|
  w.resources :sessions

# View
<%= url_for([@workshop, @session]) %>
<%= link_to('Session', [@workshop, @session]) %>
<% form_for([@workshop, @session] do |f| %>
# ...
<% end %>



Looks great. Thanks Jonathan!


Can you explain this a little more? I understand polymorphics, but
still trying to grok simply_helpful, so I'm not exactly sure what
these arrays are doing in there.

(Feel free to push this thread to rubyonrails-talk if that's more


Essentially, simply_helpful's form_for helper will try to figure out
the correct URL that it should be POSTing to based on the object you
give it. If the form is for @workshop (<% form_for @workshop do ...
%>), with is an instance of Workshop, the form will POST to /workshops
(or PUT to /workshops/123 if editing a saved instance).

If you were editing a nested resource (i.e.
/workshops/123/sessions/456), the url generation in simply_helpful did
not correctly use those nested resources. By passing an array of
objects, it's now possible for the form action url to be inferred
based on the classes of the objects in that array.

I haven't looked at how the patch here actually works, but the logic
might be something like this:

  1. take the last element of the array, since that's the most-inner
of the nested resources. In this case, that's @session
  2. infer the named route method based on that object's class, and
then pass the array as arguments to that array. So, what ends up being
called is

    sessions_path(@workshop, @session)

  which is the correct URL for this resource.



There's a bug in the version of this patch that was applied to edge.
I reopened the ticket and submitted a fix.



Thanks a lot, James - makes perfect sense now.



I believe we are now prefixing the parent resource to the named route,
so it will be workshop_sessions_path(@workshop, @sessions).


Shane has it right.

Fixed another small bug, please apply the new patch...

Added unit tests and fixes for polymorphic_url.