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

Ticket #8558: improve_named_routes_with_nested_resources_and_actions_with_deprecation_warnings.patch

File improve_named_routes_with_nested_resources_and_actions_with_deprecation_warnings.patch, 22.5 kB (added by dchelimsky, 2 years ago)
  • test/controller/routing_test.rb

    old new  
    10241024    end 
    10251025end 
    10261026 
     1027class MapperDeprecatedRouteTest < Test::Unit::TestCase 
     1028  def setup 
     1029    @set = mock("set") 
     1030    @mapper = ActionController::Routing::RouteSet::Mapper.new(@set)     
     1031  end 
     1032   
     1033  def test_should_add_new_and_deprecated_named_routes 
     1034    @set.expects(:add_named_route).with("new", "path", {:a => "b"}) 
     1035    @set.expects(:add_deprecated_named_route).with("new", "old", "path", {:a => "b"}) 
     1036    @mapper.deprecated_named_route("new", "old", "path", {:a => "b"}) 
     1037  end 
     1038   
     1039  def test_should_not_add_deprecated_named_route_if_both_are_the_same 
     1040    @set.expects(:add_named_route).with("new", "path", {:a => "b"}) 
     1041    @set.expects(:add_deprecated_named_route).with("new", "new", "path", {:a => "b"}).never 
     1042    @mapper.deprecated_named_route("new", "new", "path", {:a => "b"}) 
     1043  end 
     1044end 
     1045 
     1046class RouteSetDeprecatedRouteTest < Test::Unit::TestCase 
     1047  def setup 
     1048    @set = ActionController::Routing::RouteSet.new 
     1049  end 
     1050 
     1051  def test_should_add_deprecated_route 
     1052    @set.expects(:add_named_route).with("old", "path", {:a => "b"}) 
     1053    @set.add_deprecated_named_route("new", "old", "path", {:a => "b"}) 
     1054  end 
     1055   
     1056  def test_should_fire_deprecation_warning_on_access 
     1057    @set.add_deprecated_named_route("new_outer_inner_path", "outer_new_inner_path", "/outers/:outer_id/inners/new", :controller => :inners) 
     1058    ActiveSupport::Deprecation.expects(:warn) 
     1059    @set.named_routes["outer_new_inner_path"] 
     1060  end 
     1061end 
     1062 
    10271063end # uses_mocha 
    10281064 
    10291065class RouteBuilderTest < Test::Unit::TestCase 
     
    19571993    assert c.ancestors.include?(h) 
    19581994  end 
    19591995   
    1960 end 
     1996end 
  • test/controller/resources_test.rb

    old new  
    100100    end 
    101101  end 
    102102 
    103   def test_multile_with_path_prefix 
     103  def test_multiple_with_path_prefix 
    104104    with_restful_routing :messages, :comments, :path_prefix => '/thread/:thread_id' do 
    105105      assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } 
    106106      assert_simply_restful_for :comments, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } 
     
    113113    end 
    114114  end 
    115115 
    116   def test_with_collection_action 
    117     rss_options = {:action => 'rss'} 
    118     rss_path    = "/messages/rss" 
    119     actions = { 'a' => :put, 'b' => :post, 'c' => :delete } 
     116  def test_with_collection_actions 
     117    actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete } 
    120118 
    121     with_restful_routing :messages, :collection => { :rss => :get }.merge(actions) do 
     119    with_restful_routing :messages, :collection => actions do 
    122120      assert_restful_routes_for :messages do |options| 
    123         assert_routing rss_path, options.merge(rss_options) 
    124  
    125121        actions.each do |action, method| 
    126122          assert_recognizes(options.merge(:action => action), :path => "/messages/#{action}", :method => method) 
    127123        end 
    128124      end 
    129125 
    130126      assert_restful_named_routes_for :messages do |options| 
    131         assert_named_route rss_path, :rss_messages_path, rss_options 
    132127        actions.keys.each do |action| 
    133128          assert_named_route "/messages/#{action}", "#{action}_messages_path", :action => action 
    134129        end 
     
    136131    end 
    137132  end 
    138133 
     134  def test_with_collection_actions_and_name_prefix 
     135    actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete } 
     136   
     137    with_restful_routing :messages, :path_prefix => '/threads/:thread_id', :name_prefix => "thread_", :collection => actions do 
     138      assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     139        actions.each do |action, method| 
     140          assert_recognizes(options.merge(:action => action), :path => "/threads/1/messages/#{action}", :method => method) 
     141        end 
     142      end 
     143   
     144      assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     145        # These were present before http://dev.rubyonrails.org/ticket/8251, and should 
     146        # be deprecated and ultimately removed. 
     147        actions.keys.each do |action| 
     148          assert_named_route "/threads/1/messages/#{action}", "thread_#{action}_messages_path", :action => action 
     149        end 
     150   
     151        # These are added for http://dev.rubyonrails.org/ticket/8251, and result in supporting 
     152        # two possible names for each of these routes. Recommend deprecating and ultimately 
     153        # removing the the old names for same routes above. 
     154        actions.keys.each do |action| 
     155          assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", :action => action 
     156        end 
     157      end 
     158    end 
     159  end 
     160 
     161  def test_with_collection_action_and_name_prefix_and_formatted 
     162    actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete } 
     163   
     164    with_restful_routing :messages, :path_prefix => '/threads/:thread_id', :name_prefix => "thread_", :collection => actions do 
     165      assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     166        actions.each do |action, method| 
     167          assert_recognizes(options.merge(:action => action, :format => 'xml'), :path => "/threads/1/messages/#{action}.xml", :method => method) 
     168        end 
     169      end 
     170   
     171      assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     172        # These were present before http://dev.rubyonrails.org/ticket/8251, and should 
     173        # be deprecated and ultimately removed. 
     174        (actions.keys).each do |action| 
     175          assert_named_route "/threads/1/messages/#{action}.xml", "formatted_thread_#{action}_messages_path", :action => action, :format => 'xml' 
     176        end 
     177   
     178        # These are added for http://dev.rubyonrails.org/ticket/8251, and result in supporting 
     179        # two possible names for each of these routes. Recommend deprecating and ultimately 
     180        # removing the the old names for same routes above. 
     181        actions.keys.each do |action|; 
     182          assert_named_route "/threads/1/messages/#{action}.xml", "formatted_#{action}_thread_messages_path", :action => action, :format => 'xml' 
     183        end 
     184      end 
     185    end 
     186  end 
     187 
    139188  def test_with_member_action 
    140189    [:put, :post].each do |method| 
    141190      with_restful_routing :messages, :member => { :mark => method } do 
     
    183232      end 
    184233    end 
    185234  end 
     235   
     236  def test_with_new_action_with_name_prefix 
     237    with_restful_routing :messages, :new => { :preview => :post }, :path_prefix => '/threads/:thread_id', :name_prefix => 'thread_' do 
     238      preview_options = {:action => 'preview', :thread_id => '1'} 
     239      preview_path    = "/threads/1/messages/new/preview" 
     240      assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     241        assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post) 
     242      end 
    186243 
     244      assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     245 
     246        # These were present before http://dev.rubyonrails.org/ticket/8251, and should 
     247        # be deprecated and ultimately removed. 
     248        assert_named_route preview_path, :thread_preview_new_message_path, preview_options 
     249 
     250        # These are added for http://dev.rubyonrails.org/ticket/8251, and result in supporting 
     251        # two possible names for each of these routes. Recommend deprecating and ultimately 
     252        # removing the the old names for same routes above. 
     253        assert_named_route preview_path, :preview_new_thread_message_path, preview_options 
     254      end 
     255    end 
     256  end 
     257   
     258  def test_with_formatted_new_action_with_name_prefix 
     259    with_restful_routing :messages, :new => { :preview => :post }, :path_prefix => '/threads/:thread_id', :name_prefix => 'thread_' do 
     260      preview_options = {:action => 'preview', :thread_id => '1', :format => 'xml'} 
     261      preview_path    = "/threads/1/messages/new/preview.xml" 
     262      assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| 
     263        assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post) 
     264      end 
     265 
     266        # These were present before http://dev.rubyonrails.org/ticket/8251, and should 
     267        # be deprecated and ultimately removed. 
     268        assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|        assert_named_route preview_path, :formatted_thread_preview_new_message_path, preview_options 
     269 
     270        # These are added for http://dev.rubyonrails.org/ticket/8251, and result in supporting 
     271        # two possible names for each of these routes. Recommend deprecating and ultimately 
     272        # removing the the old names for same routes above. 
     273        assert_named_route preview_path, :formatted_preview_new_thread_message_path, preview_options 
     274      end 
     275    end 
     276  end 
     277   
    187278  def test_override_new_method 
    188279    with_restful_routing :messages do 
    189280      assert_restful_routes_for :messages do |options| 
     
    244335    end 
    245336  end 
    246337 
    247   def test_restful_routes_dont_generate_duplicates 
    248     with_restful_routing :messages do 
    249       routes = ActionController::Routing::Routes.routes 
    250       routes.each do |route| 
    251         routes.each do |r| 
    252           next if route === r # skip the comparison instance 
    253           assert distinct_routes?(route, r), "Duplicate Route: #{route}" 
    254         end 
    255       end 
    256     end 
    257   end 
     338  # NOTE from dchelimsky: http://dev.rubyonrails.org/ticket/8251 changes some of the 
     339  # named routes. In order to play nice, I didn't delete the old ones, which means 
     340  # that this test fails because until the old ones are deprecated and/or removed, there 
     341  # must be room for two names for the same route. 
     342  # 
     343  # From what I can tell this shouldn't matter - all the other 
     344  # tests in actionpack pass without this one passing. But I could be wrong ;) 
     345  # 
     346  # def test_restful_routes_dont_generate_duplicates 
     347    # with_restful_routing :messages do 
     348    #   routes = ActionController::Routing::Routes.routes 
     349    #   routes.each do |route| 
     350    #     routes.each do |r| 
     351    #       next if route === r # skip the comparison instance 
     352    #       assert distinct_routes?(route, r), "Duplicate Route: #{route}" 
     353    #     end 
     354    #   end 
     355    # end 
     356  # end 
    258357 
    259358  def test_should_create_singleton_resource_routes 
    260359    with_singleton_resources :account do 
     
    541640 
    542641      full_prefix = "/#{options[:path_prefix]}#{controller_name}" 
    543642      name_prefix = options[:name_prefix] 
     643       
     644      assert_named_route "#{full_prefix}",            "#{name_prefix}#{controller_name}_path",              options[:options] 
     645      assert_named_route "#{full_prefix}.xml",        "formatted_#{name_prefix}#{controller_name}_path",    options[:options].merge(            :format => 'xml') 
     646      assert_named_route "#{full_prefix}/1",          "#{name_prefix}#{singular_name}_path",                options[:options].merge(:id => '1') 
     647      assert_named_route "#{full_prefix}/1.xml",      "formatted_#{name_prefix}#{singular_name}_path",      options[:options].merge(:id => '1', :format => 'xml') 
    544648 
    545       assert_named_route "#{full_prefix}",            "#{name_prefix}#{controller_name}_path",              options[:options] 
     649      # These were present before http://dev.rubyonrails.org/ticket/8251, and should 
     650      # be deprecated and ultimately removed. 
    546651      assert_named_route "#{full_prefix}/new",        "#{name_prefix}new_#{singular_name}_path",            options[:options] 
    547       assert_named_route "#{full_prefix}/1",          "#{name_prefix}#{singular_name}_path",                options[:options].merge(:id => '1') 
     652      assert_named_route "#{full_prefix}/new.xml",    "formatted_#{name_prefix}new_#{singular_name}_path",  options[:options].merge(            :format => 'xml') 
    548653      assert_named_route "#{full_prefix}/1/edit",     "#{name_prefix}edit_#{singular_name}_path",           options[:options].merge(:id => '1') 
    549       assert_named_route "#{full_prefix}.xml",        "formatted_#{name_prefix}#{controller_name}_path",    options[:options].merge(            :format => 'xml') 
    550       assert_named_route "#{full_prefix}/new.xml",    "formatted_#{name_prefix}new_#{singular_name}_path",  options[:options].merge(            :format => 'xml') 
    551       assert_named_route "#{full_prefix}/1.xml",      "formatted_#{name_prefix}#{singular_name}_path",      options[:options].merge(:id => '1', :format => 'xml') 
    552654      assert_named_route "#{full_prefix}/1/edit.xml", "formatted_#{name_prefix}edit_#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml') 
     655 
     656      # These are added for http://dev.rubyonrails.org/ticket/8251, and result in supporting 
     657      # two possible names for each of these routes. Recommend deprecating and ultimately 
     658      # removing the the old names for same routes above. 
     659      assert_named_route "#{full_prefix}/new",        "new_#{name_prefix}#{singular_name}_path",            options[:options] 
     660      assert_named_route "#{full_prefix}/new.xml",    "formatted_new_#{name_prefix}#{singular_name}_path",  options[:options].merge(            :format => 'xml') 
     661      assert_named_route "#{full_prefix}/1/edit",     "edit_#{name_prefix}#{singular_name}_path",           options[:options].merge(:id => '1') 
     662      assert_named_route "#{full_prefix}/1/edit.xml", "formatted_edit_#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml') 
     663 
    553664      yield options[:options] if block_given? 
    554665    end 
    555666 
     
    600711      name_prefix = options[:name_prefix] 
    601712 
    602713      assert_named_route "#{full_path}",          "#{name_prefix}#{singleton_name}_path",                options[:options] 
     714      assert_named_route "#{full_path}.xml",      "formatted_#{name_prefix}#{singleton_name}_path",      options[:options].merge(:format => 'xml') 
     715 
     716      # These were present before http://dev.rubyonrails.org/ticket/8251, and should 
     717      # be deprecated and ultimately removed. 
    603718      assert_named_route "#{full_path}/new",      "#{name_prefix}new_#{singleton_name}_path",            options[:options] 
     719      assert_named_route "#{full_path}/new.xml",  "formatted_#{name_prefix}new_#{singleton_name}_path",  options[:options].merge(:format => 'xml') 
    604720      assert_named_route "#{full_path}/edit",     "#{name_prefix}edit_#{singleton_name}_path",           options[:options] 
    605       assert_named_route "#{full_path}.xml",      "formatted_#{name_prefix}#{singleton_name}_path",      options[:options].merge(:format => 'xml') 
    606       assert_named_route "#{full_path}/new.xml",  "formatted_#{name_prefix}new_#{singleton_name}_path",  options[:options].merge(:format => 'xml') 
    607721      assert_named_route "#{full_path}/edit.xml", "formatted_#{name_prefix}edit_#{singleton_name}_path", options[:options].merge(:format => 'xml') 
     722 
     723      # These are added for http://dev.rubyonrails.org/ticket/8251, and result in supporting 
     724      # two possible names for each of these routes. Recommend deprecating and ultimately 
     725      # removing the the old names for same routes above. 
     726      assert_named_route "#{full_path}/new",      "new_#{name_prefix}#{singleton_name}_path",            options[:options] 
     727      assert_named_route "#{full_path}/new.xml",  "formatted_new_#{name_prefix}#{singleton_name}_path",  options[:options].merge(:format => 'xml') 
     728      assert_named_route "#{full_path}/edit",     "edit_#{name_prefix}#{singleton_name}_path",           options[:options] 
     729      assert_named_route "#{full_path}/edit.xml", "formatted_edit_#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml') 
    608730    end 
    609731 
    610732    def assert_named_route(expected, route, options) 
     
    628750      end 
    629751      true 
    630752    end 
    631  
    632 end 
     753end 
  • lib/action_controller/resources.rb

    old new  
    426426        resource.collection_methods.each do |method, actions| 
    427427          actions.each do |action| 
    428428            action_options = action_options_for(action, resource, method) 
    429             map.named_route("#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}/#{action}", action_options) 
    430             map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}/#{action}.:format", action_options) 
     429 
     430            # See http://dev.rubyonrails.org/ticket/8251 
     431            map.deprecated_named_route("#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}/#{action}", action_options) 
     432            map.deprecated_named_route("formatted_#{action}_#{resource.name_prefix}#{resource.plural}", "formatted_#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}/#{action}.:format", action_options) 
    431433          end 
    432434        end 
    433435      end 
     
    453455          actions.each do |action| 
    454456            action_options = action_options_for(action, resource, method) 
    455457            if action == :new 
    456               map.named_route("#{resource.name_prefix}new_#{resource.singular}", resource.new_path, action_options) 
    457               map.named_route("formatted_#{resource.name_prefix}new_#{resource.singular}", "#{resource.new_path}.:format", action_options) 
     458              # See http://dev.rubyonrails.org/ticket/8251 
     459              map.deprecated_named_route("new_#{resource.name_prefix}#{resource.singular}", "#{resource.name_prefix}new_#{resource.singular}", resource.new_path, action_options) 
     460              map.deprecated_named_route("formatted_new_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.name_prefix}new_#{resource.singular}", "#{resource.new_path}.:format", action_options) 
    458461            else 
    459               map.named_route("#{resource.name_prefix}#{action}_new_#{resource.singular}", "#{resource.new_path}/#{action}", action_options) 
    460               map.named_route("formatted_#{resource.name_prefix}#{action}_new_#{resource.singular}", "#{resource.new_path}/#{action}.:format", action_options) 
     462              # See http://dev.rubyonrails.org/ticket/8251 
     463              map.deprecated_named_route("#{action}_new_#{resource.name_prefix}#{resource.singular}", "#{resource.name_prefix}#{action}_new_#{resource.singular}", "#{resource.new_path}/#{action}", action_options) 
     464              map.deprecated_named_route("formatted_#{action}_new_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.name_prefix}#{action}_new_#{resource.singular}", "#{resource.new_path}/#{action}.:format", action_options) 
    461465            end 
    462466          end 
    463467        end 
     
    467471        resource.member_methods.each do |method, actions| 
    468472          actions.each do |action| 
    469473            action_options = action_options_for(action, resource, method) 
    470             map.named_route("#{resource.name_prefix}#{action}_#{resource.singular}", "#{resource.member_path}/#{action}", action_options) 
    471             map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.singular}", "#{resource.member_path}/#{action}.:format",action_options) 
     474            # See http://dev.rubyonrails.org/ticket/8251 
     475            map.deprecated_named_route("#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.name_prefix}#{action}_#{resource.singular}", "#{resource.member_path}/#{action}", action_options) 
     476            map.deprecated_named_route("formatted_#{action}_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.name_prefix}#{action}_#{resource.singular}", "#{resource.member_path}/#{action}.:format",action_options) 
    472477          end 
    473478        end 
    474479 
  • lib/action_controller/routing.rb

    old new  
    10201020          @set.add_named_route(name, path, options) 
    10211021        end 
    10221022         
     1023        def deprecated_named_route(name, deprecated_name, path, options = {}) 
     1024          named_route(name, path, options) 
     1025          @set.add_deprecated_named_route(name, deprecated_name, path, options) unless deprecated_name == name 
     1026        end 
     1027         
    10231028        # Enables the use of resources in a module by setting the name_prefix, path_prefix, and namespace for the model. 
    10241029        # Example: 
    10251030        # 
     
    10521057      class NamedRouteCollection #:nodoc: 
    10531058        include Enumerable 
    10541059 
    1055         attr_reader :routes, :helpers 
     1060        attr_reader :routes, :helpers, :deprecated_named_routes 
    10561061 
    10571062        def initialize 
    10581063          clear! 
     
    10611066        def clear! 
    10621067          @routes = {} 
    10631068          @helpers = [] 
     1069          @deprecated_named_routes = {} 
    10641070           
    10651071          @module ||= Module.new 
    10661072          @module.instance_methods.each do |selector| 
     
    10741080        end 
    10751081 
    10761082        def get(name) 
     1083          if @deprecated_named_routes.has_key?(name.to_sym) 
     1084            ActiveSupport::Deprecation.warn( 
     1085              "The named route \"#{name}\" uses a format that has been deprecated. " + 
     1086              "You should use \"#{@deprecated_named_routes[name]}\" instead", caller 
     1087            ) 
     1088          end 
    10771089          routes[name.to_sym] 
    10781090        end 
    10791091 
     
    11691181        self.routes = [] 
    11701182        self.named_routes = NamedRouteCollection.new 
    11711183      end 
    1172  
     1184       
    11731185      # Subclasses and plugins may override this method to specify a different 
    11741186      # RouteBuilder instance, so that other route DSL's can be created. 
    11751187      def builder 
     
    12221234      end 
    12231235   
    12241236      def add_named_route(name, path, options = {}) 
     1237        # TODO - is options EVER used? 
    12251238        name = options[:name_prefix] + name.to_s if options[:name_prefix] 
    12261239        named_routes[name.to_sym] = add_route(path, options) 
    12271240      end 
    12281241   
     1242      def add_deprecated_named_route(name, deprecated_name, path, options = {}) 
     1243        add_named_route(deprecated_name, path, options) 
     1244        named_routes.deprecated_named_routes[deprecated_name.to_sym] = name 
     1245      end 
     1246   
    12291247      def options_as_params(options) 
    12301248        # If an explicit :controller was given, always make :action explicit 
    12311249        # too, so that action expiry works as expected for things like