I really hate calling polymorphic_path directly. I really love what it does for me behind the scenes but I think named routes are much more descriptive. IMHO, polymorphic_path and polymorphic_url should go protected from direct calls.
If you've named your instance variables descriptively, the polymorphic_url syntax is descriptive -- it shows the objects that appear in the url, and the order in which they appear:
polymorphic_url [@company, @person]
I agree. DHH said earlier that he thought url_for should never be called explicitly; I won't go that far but I do think that polymorphic_url should stay behind the scenes.
Currently, polymorphic_url can be called behind-the-scenes like this:
<%= link_to @person.name, [@company, @person] %>
which generates http://www.example.com/companies/1/people/5
But if you want to create a link to /companies/1/people/new, / companies/1/people/5/edit, /companies/1/people.atom, etc., you need to call polymorphic_url (specifically, new_polymorphic_url, edit_polymorphic_url and formatted_polymorphic_url) -- example:
<%= link_to 'New Person', new_polymorphic_url [@company, @person] %>
(...although currently, new_polymorphic_url fails with multiple arguments because polymorphic_url doesn't call the correct named route; I've fixed this here: http://dev.rubyonrails.org/ticket/8719 )
The real gain for me is, when you've got a view that supports scoping of the resource by different parents, you can avoid putting in logic to build links appropriately, and just do:
<%= link_to 'New Person', new_polymorphic_url [@parent, @person] %>
... and the link will either be to /categories/1/people/new or / companies/19/people/new, depending upon if @parent is set to a Category or Company. And with this patch -- http://dev.rubyonrails.org/ticket/8705 -- if @parent is nil, you'll just get /people/new
This seems useful -- link_to can accommodate any nesting situation without wrapping it up in a custom helper, just so that the correct named route can be called.
I try to avoid the complex nested routing situations that you've described. link_to 'New Person', company_new_person_path(@company) already works great for me.
<%= link_to 'New Person', new_polymorphic_url [@company, @person] %>
But here you know you have a company already. I don't really see the utility of extending those cases unless there are common use cases where you *don't* know what the first part of the url is.
The use case where you wouldn't know the first part of the url would be:
<%= link_to 'New Person', new_polymorphic_url [@parent, @person] %>
...where @parent could be an instance of Company, and instance of Category, or nil. @parent would be set in the controller, based upon whether :company_id or :category_id were in the params (this technique is detailed in this post: Revolution On Rails: DRYing Up Polymorphic Controllers )
Depending upon the value of @parent, the outputted href would be one of the following:
/people/new /categories/5/people/new /companies/12/people/new
So instead of doing conditional logic to decide whether to call new_person_url, category_new_person_url(@category), or company_new_person_url(@company), I'm just calling new_polymorphic_url, and leveraging the logic built in to that.
One last request for someone from core to look at this patch: [
http://dev.rubyonrails.org/ticket/8640](http://dev.rubyonrails.org/ticket/8640) and then I’ll shut up.
If this isn’t something appropriate for core just give me a heads up and I’ll extract into a plugin.
One last request for someone from core to look at this patch: http://dev.rubyonrails.org/ticket/8640 and then I'll shut up.
If this isn't something appropriate for core just give me a heads up and I'll extract into a plugin.
I think it looks fine, it covers the simple case of [:admin, @customer] which works for me. If tobi has no objections, it looks good to go.