Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7454: disambiguate_url_generators_for_uncountable_resources.patch

File disambiguate_url_generators_for_uncountable_resources.patch, 6.3 kB (added by jkit, 2 years ago)

patch to fix bug exhibited by test case in ticket #7422

  • test/controller/resources_test.rb

    old new  
    99class ThreadsController  < ResourcesController; end 
    1010class MessagesController < ResourcesController; end 
    1111class CommentsController < ResourcesController; end 
     12class SheepController < ResourcesController; end 
    1213 
    1314class AccountController <  ResourcesController; end 
    1415class AdminController   <  ResourcesController; end 
     
    5152  end 
    5253 
    5354  def test_multiple_default_restful_routes 
    54     with_restful_routing :messages, :comments do 
     55    with_restful_routing :messages, :comments, :sheep do 
    5556      assert_simply_restful_for :messages 
    5657      assert_simply_restful_for :comments 
     58      assert_simply_restful_for :sheep 
    5759    end 
    5860  end 
    5961 
     
    391393      get :index, options[:options] 
    392394      options[:options].delete :action 
    393395 
     396      collection_name = controller_name.to_s + 
     397        if Inflector.inflections.uncountables.include?(controller_name.to_s) 
     398          ActionController::Resources::Resource::UNCOUNTABLE_COLLECTION_SUFFIX 
     399        else 
     400          "" 
     401        end 
     402 
    394403      full_prefix = "/#{options[:path_prefix]}#{controller_name}" 
    395404      name_prefix = options[:name_prefix] 
    396405 
    397       assert_named_route "#{full_prefix}",            "#{name_prefix}#{controller_name}_path",              options[:options] 
     406      assert_named_route "#{full_prefix}",            "#{name_prefix}#{collection_name}_path",              options[:options] 
    398407      assert_named_route "#{full_prefix}/new",        "#{name_prefix}new_#{singular_name}_path",            options[:options] 
    399408      assert_named_route "#{full_prefix}/1",          "#{name_prefix}#{singular_name}_path",                options[:options].merge(:id => '1') 
    400409      assert_named_route "#{full_prefix}/1;edit",     "#{name_prefix}edit_#{singular_name}_path",           options[:options].merge(:id => '1') 
    401       assert_named_route "#{full_prefix}.xml",        "formatted_#{name_prefix}#{controller_name}_path",    options[:options].merge(            :format => 'xml') 
     410      assert_named_route "#{full_prefix}.xml",        "formatted_#{name_prefix}#{collection_name}_path",    options[:options].merge(            :format => 'xml') 
    402411      assert_named_route "#{full_prefix}/new.xml",    "formatted_#{name_prefix}new_#{singular_name}_path",  options[:options].merge(            :format => 'xml') 
    403412      assert_named_route "#{full_prefix}/1.xml",      "formatted_#{name_prefix}#{singular_name}_path",      options[:options].merge(:id => '1', :format => 'xml') 
    404413      assert_named_route "#{full_prefix}/1.xml;edit", "formatted_#{name_prefix}edit_#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml') 
  • lib/action_controller/resources.rb

    old new  
    11module ActionController 
    22  module Resources 
    33    class Resource #:nodoc: 
     4       
     5      UNCOUNTABLE_COLLECTION_SUFFIX = "_collection" 
     6 
    47      attr_reader :collection_methods, :member_methods, :new_methods 
    58      attr_reader :path_prefix, :name_prefix 
    69      attr_reader :plural, :singular 
     
    3639      def nesting_path_prefix 
    3740        @nesting_path_prefix ||= "#{path}/:#{singular}_id" 
    3841      end 
     42 
     43      def collection_name 
     44        if @plural.to_s == @singular.to_s # uncountable 
     45          "#{@plural}#{UNCOUNTABLE_COLLECTION_SUFFIX}" 
     46        else 
     47          "#{@plural}" 
     48        end 
     49      end 
    3950       
    4051      protected 
    4152        def arrange_actions 
     
    141152    #   edit_message  edit_message_url(id), hash_for_edit_message_url(id), 
    142153    #                 edit_message_path(id), hash_for_edit_message_path(id) 
    143154    # 
     155    # Note that for resources with names that are uncountable, there must be a way to disambiguate 
     156    # a call to the collection url generators and the member url generators.  Take for example the 
     157    # resource "sheep".  Without disambiguation, <tt>sheep_url()</tt> can only refer to either the  
     158    # collection url generator, or the member url generator, leaving the other without a method to 
     159    # name.  To resolve this, we make uncountable resources a special case, and append the 
     160    # resource name with ActiveController::Resources::Resource::UNCOUNTABLE_COLLECTION_SUFFIX  
     161    # (which by default is "_collection").  This results in the method <tt>sheep_collection_url</tt> 
     162    # as the generator for the collection, and <tt>sheep_url</tt> as the generator for the member. 
     163    # 
    144164    # You can use these helpers instead of #url_for or methods that take #url_for parameters: 
    145165    #  
    146166    #   redirect_to :controller => 'messages', :action => 'index' 
     
    324344        resource.collection_methods.each do |method, actions| 
    325345          actions.each do |action| 
    326346            action_options = action_options_for(action, resource, method) 
    327             map.named_route("#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path};#{action}", action_options) 
    328             map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}.:format;#{action}", action_options) 
     347            map.named_route("#{resource.name_prefix}#{action}_#{resource.collection_name}", "#{resource.path};#{action}", action_options) 
     348            map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.collection_name}", "#{resource.path}.:format;#{action}", action_options) 
    329349          end 
    330350        end 
    331351      end 
    332352 
    333353      def map_default_collection_actions(map, resource) 
    334354        index_action_options = action_options_for("index", resource) 
    335         map.named_route("#{resource.name_prefix}#{resource.plural}", resource.path, index_action_options) 
    336         map.named_route("formatted_#{resource.name_prefix}#{resource.plural}", "#{resource.path}.:format", index_action_options) 
     355        map.named_route("#{resource.name_prefix}#{resource.collection_name}", resource.path, index_action_options) 
     356        map.named_route("formatted_#{resource.name_prefix}#{resource.collection_name}", "#{resource.path}.:format", index_action_options) 
    337357 
    338358        create_action_options = action_options_for("create", resource) 
    339359        map.connect(resource.path, create_action_options)