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.

polymorphic_path breaks on uncountable resources

#411

It seems that passing an uncountable resource to polymorphic_path and associated methods causes an exception to be thrown.

This causes an exception for me on Rails 2.1 under Ruby 1.8.6

Migration

create_table :sheep do |t|
  t.string :name

  t.timestamps
end

Model

class Sheep < ActiveRecord::Base
end

Routes

ActionController::Routing::Routes.draw do |map|
  map.resources :sheep, :singular => :sheep_instance

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

$ script/console

Loading development environment (Rails 2.1.0)

>> sheep = Sheep.create(:name => 'Dolly')

=> #

>> app.polymorphic_path(sheep)

NoMethodError: You have a nil object when you didn't expect it!

The error occurred while evaluating nil.to_sym

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/routing/route.rb:145:in `extra_keys'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/routing/route.rb:145:in `map'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/routing/route.rb:145:in `extra_keys'

from generated code (/Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/routing/route.rb:45):3:in `generate'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/routing/route.rb:122:in `generate'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/routing/route_set.rb:337:in `generate'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/url_rewriter.rb:131:in `rewrite_path'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/url_rewriter.rb:110:in `rewrite_url'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/url_rewriter.rb:88:in `rewrite'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/integration.rb:218:in `url_for'

from (eval):17:in `sheep_path'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/polymorphic_routes.rb:101:in `send!'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/polymorphic_routes.rb:101:in `polymorphic_url'

from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/polymorphic_routes.rb:108:in `polymorphic_path'

from (irb):2

Reported by Andy Gregorowicz · June 13th, 2008 @ 07:59 PM

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

Activity

  1. Andy Gregorowicz
    Andy Gregorowicz

    The problem seems to be that RecordIdentifier is used to determine the singular class name, which is then used to generate the named route call. So for instance, when calling

    
    polymorphic_path(sheep) 
    
    

    RecordIdentifier will be called and come up with the singular class name of sheep and the following route will be called.

    
    sheep_path(sheep) 
    
    

    When it should be

    
    sheep_instance_path(sheep)
    
    

    RecordIdentifier doesn't know about the :singular option passed into the route definition. I'm not sure what would be the best way to fix this... Any suggestions?

    June 19th, 2008 @ 04:27 PM

  2. Zach Carter
    Zach Carter
    • Tag set to 2.1, actionpack, bug

    Currently I patch RecordIdentifier to add _instance to the class name if the singular and plural are the same:

    module ActionController  
      module RecordIdentifier
        # Returns the singular class name of a record or class. Examples:
        #
        #   singular_class_name(post)             # => "post"
        #   singular_class_name(Highrise::Person) # => "highrise_person"
        #   singular_class_name(sheep)             # => "sheep_instance"
        def singular_class_name(record_or_class)
          model_name = model_name_from_record_or_class(record_or_class)
          model_name.singular + (model_name.singular == model_name.plural ? '_instance':'')
        end
      end
    end
    

    Still looking for a proper fix.

    July 30th, 2008 @ 09:39 PM

  3. ideaoforder
    ideaoforder

    Thanks for the monkey patch! This has been driving me nuts. I guess the moral of the story is never use any uncountable nouns.

    This did produce a problem for me, in that the plural_class_name method just pluralizes the output of the above patch. So I had to add a custom method for that as well:

    def plural_class_name(record_or_class) class_from_record_or_class(record_or_class).name.underscore.tr('/', '_').pluralize end

    October 30th, 2008 @ 08:12 PM

  4. Marcello Nuccio
    Marcello Nuccio

    By default rails uses name_index_url as plural named route of uncountable names. The attached patch fixes build_named_route_call() to do the same while building named routes. So it solves the bug if you use rails defaults.

    Tests included.

    January 3rd, 2009 @ 01:39 PM

  5. Eric O'Connell
    Eric O'Connell

    Marcello, I just ran into this problem myself, and the patch worked as advertised. Thanks!

    January 20th, 2009 @ 04:14 AM

  6. CancelProfileIsBroken
    CancelProfileIsBroken

    Differently broken under 2.3 final:

    
    
    Loading development environment (Rails 2.3.2)
    >> sheep = Sheep.create(:name => 'Dolly')
    => #<Sheep id: 1, name: "Dolly", created_at: "2009-03-16 15:19:59", updated_at: "2009-03-16 15:19:59">
    >> app.polymorphic_path(sheep)
    => "/sheep.%23%3Csheep:0x20b9b5c%3E"
    
    

    March 16th, 2009 @ 03:24 PM

  7. Brendon
    Brendon

    Yep this is definitely broken. How do we get this sorted out?

    March 23rd, 2009 @ 01:51 AM

  8. CancelProfileIsBroken
    CancelProfileIsBroken
    • State changed from new to open

    http://github.com/rails/rails/co... is the commit that introduced the issue. Looking at a possible patch now.

    March 24th, 2009 @ 01:41 PM

  9. Brendon
    Brendon

    Thanks Mike, I really appreciate your help :)

    The original point of this ticket (incorrectly generated polymorphic paths on uncountable resources) seems to be a separate bug, that's the only reason I started a new ticket :)

    Also, I noticed that the patch above is no longer valid in 2.3.2 as the code it fixes has been modified some.

    March 24th, 2009 @ 09:31 PM

  10. Brendon
    Brendon
    • Assigned user set to CancelProfileIsBroken

    I've done some investigation, and I think the problem lies even deeper than that code change. I commented out the code and the result was:

    /admin/1/podcast_series.1

    or in your example:

    /sheep.1

    Seems that it is interpreting the uncountable resource as a format rather than a path segment.

    Do you have any insights into where I might find that particular piece of code? :)

    March 29th, 2009 @ 10:37 PM

  11. CancelProfileIsBroken
    CancelProfileIsBroken

    Brendon - On deeper investigation, there's a fundamental mismatch between this sort of routing and the use of polymorphic_url. The basic issue is that polymorphic_url doesn't know anything about inflections specified as part of routing.

    There are a couple of us kicking around ideas for a possible patch. Drop me a line (MikeG1@larkfarm.com) and you can help us brainstorm.

    March 29th, 2009 @ 10:57 PM

  12. CancelProfileIsBroken
  13. Marc Dequènes (Duck)
    Marc Dequènes (Duck)
    • Importance changed from to

    Adapted fix for 2.3.5.

    July 11th, 2010 @ 09:21 PM

  14. Marc Dequènes (Duck)
    Marc Dequènes (Duck)
    • Tag changed from 2.1, actionpack, bug to 2.1, 2.3.x, actionpack, bug

    July 11th, 2010 @ 09:31 PM

  15. Santiago Pastorino
    Santiago Pastorino
    • Tag changed from 2.1, 2.3.x, actionpack, bug to 21, 23x, actionpack, bug

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    February 2nd, 2011 @ 04:36 PM

  16. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 2nd, 2011 @ 04:36 PM