<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,7 @@
 *2.3.0 [Edge]*
 
+* Dropped formatted_* routes in favor of just passing in :format as an option. This cuts resource routes generation in half #1359 [aaronbatalion]
+
 * Remove support for old double-encoded cookies from the cookie store.  These values haven't been generated since before 2.1.0, and any users who have visited the app in the intervening 6 months will have had their cookie upgraded. [Koz]
 
 * Allow helpers directory to be overridden via ActionController::Base.helpers_dir #1424 [Sam Pohlenz]</diff>
      <filename>actionpack/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -639,10 +639,8 @@ module ActionController
           formatted_route_path = &quot;#{route_path}.:format&quot;
 
           if route_name &amp;&amp; @set.named_routes[route_name.to_sym].nil?
-            map.named_route(route_name, route_path, action_options)
-            map.named_route(&quot;formatted_#{route_name}&quot;, formatted_route_path, action_options)
+            map.named_route(route_name, formatted_route_path, action_options)
           else
-            map.connect(route_path, action_options)
             map.connect(formatted_route_path, action_options)
           end
         end</diff>
      <filename>actionpack/lib/action_controller/resources.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,6 +34,8 @@ module ActionController
       def segment_for(string)
         segment =
           case string
+            when  /\A\.(:format)?\// 
+              OptionalFormatSegment.new
             when /\A:(\w+)/
               key = $1.to_sym
               key == :controller ? ControllerSegment.new(key) : DynamicSegment.new(key)</diff>
      <filename>actionpack/lib/action_controller/routing/builder.rb</filename>
    </modified>
    <modified>
      <diff>@@ -65,7 +65,7 @@ module ActionController
       # rather than triggering the expensive logic in +url_for+.
       class PositionalArguments &lt; Optimiser
         def guard_conditions
-          number_of_arguments = route.segment_keys.size
+          number_of_arguments = route.required_segment_keys.size
           # if they're using foo_url(:id=&gt;2) it's one
           # argument, but we don't want to generate /foos/id2
           if number_of_arguments == 1</diff>
      <filename>actionpack/lib/action_controller/routing/optimisations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,6 +35,11 @@ module ActionController
           segment.key if segment.respond_to? :key
         end.compact
       end
+      
+      def required_segment_keys
+        required_segments = segments.select {|seg| (!seg.optional? &amp;&amp; !seg.is_a?(DividerSegment)) || seg.is_a?(PathSegment) }
+        required_segments.collect { |seg| seg.key if seg.respond_to?(:key)}.compact
+      end
 
       # Build a query string from the keys of the given hash. If +only_keys+
       # is given (as an array), only the keys indicated will be used to build</diff>
      <filename>actionpack/lib/action_controller/routing/route.rb</filename>
    </modified>
    <modified>
      <diff>@@ -185,6 +185,14 @@ module ActionController
                 end
 
                 url_for(#{hash_access_method}(opts))
+                
+              end
+              #Add an alias to support the now deprecated formatted_* URL.
+              def formatted_#{selector}(*args)
+                ActiveSupport::Deprecation.warn(
+                  &quot;formatted_#{selector}() has been deprecated. please pass format to the standard&quot; +
+                  &quot;#{selector}() method instead.&quot;, caller)
+                #{selector}(*args)
               end
               protected :#{selector}
             end_eval
@@ -361,7 +369,7 @@ module ActionController
           end
 
           # don't use the recalled keys when determining which routes to check
-          routes = routes_by_controller[controller][action][options.keys.sort_by { |x| x.object_id }]
+          routes = routes_by_controller[controller][action][options.reject {|k,v| !v}.keys.sort_by { |x| x.object_id }]
 
           routes.each do |route|
             results = route.__send__(method, options, merged, expire_on)</diff>
      <filename>actionpack/lib/action_controller/routing/route_set.rb</filename>
    </modified>
    <modified>
      <diff>@@ -308,5 +308,36 @@ module ActionController
         end
       end
     end
+    
+    # The OptionalFormatSegment allows for any resource route to have an optional
+    # :format, which decreases the amount of routes created by 50%.
+    class OptionalFormatSegment &lt; DynamicSegment
+    
+      def initialize(key = nil, options = {})
+        super(:format, {:optional =&gt; true}.merge(options))            
+      end
+    
+      def interpolation_chunk
+        &quot;.&quot; + super
+      end
+    
+      def regexp_chunk
+        '(\.[^/?\.]+)?'
+      end
+    
+      def to_s
+        '(.:format)?'
+      end
+    
+      #the value should not include the period (.)
+      def match_extraction(next_capture)
+        %[
+          if (m = match[#{next_capture}])
+            params[:#{key}] = URI.unescape(m.from(1))
+          end
+        ]
+      end
+    end
+    
   end
 end</diff>
      <filename>actionpack/lib/action_controller/routing/segments.rb</filename>
    </modified>
    <modified>
      <diff>@@ -187,7 +187,7 @@ class ResourcesTest &lt; ActionController::TestCase
 
       assert_restful_named_routes_for :messages, :path_prefix =&gt; 'threads/1/', :name_prefix =&gt; 'thread_', :options =&gt; { :thread_id =&gt; '1' } do |options|
         actions.keys.each do |action|
-          assert_named_route &quot;/threads/1/messages/#{action}.xml&quot;, &quot;formatted_#{action}_thread_messages_path&quot;, :action =&gt; action, :format =&gt; 'xml'
+          assert_named_route &quot;/threads/1/messages/#{action}.xml&quot;, &quot;#{action}_thread_messages_path&quot;, :action =&gt; action, :format =&gt; 'xml'
         end
       end
     end
@@ -316,7 +316,7 @@ class ResourcesTest &lt; ActionController::TestCase
       end
 
       assert_restful_named_routes_for :messages, :path_prefix =&gt; 'threads/1/', :name_prefix =&gt; 'thread_', :options =&gt; { :thread_id =&gt; '1' } do |options|
-        assert_named_route preview_path, :formatted_preview_new_thread_message_path, preview_options
+        assert_named_route preview_path, :preview_new_thread_message_path, preview_options
       end
     end
   end
@@ -1130,14 +1130,14 @@ class ResourcesTest &lt; ActionController::TestCase
       end
 
       assert_named_route &quot;#{full_path}&quot;, &quot;#{name_prefix}#{controller_name}_path&quot;, options[:options]
-      assert_named_route &quot;#{full_path}.xml&quot;, &quot;formatted_#{name_prefix}#{controller_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}.xml&quot;, &quot;#{name_prefix}#{controller_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
       assert_named_route &quot;#{shallow_path}/1&quot;, &quot;#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1')
-      assert_named_route &quot;#{shallow_path}/1.xml&quot;, &quot;formatted_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1', :format =&gt; 'xml')
+      assert_named_route &quot;#{shallow_path}/1.xml&quot;, &quot;#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1', :format =&gt; 'xml')
 
       assert_named_route &quot;#{full_path}/#{new_action}&quot;, &quot;new_#{name_prefix}#{singular_name}_path&quot;, options[:options]
-      assert_named_route &quot;#{full_path}/#{new_action}.xml&quot;, &quot;formatted_new_#{name_prefix}#{singular_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}/#{new_action}.xml&quot;, &quot;new_#{name_prefix}#{singular_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
       assert_named_route &quot;#{shallow_path}/1/#{edit_action}&quot;, &quot;edit_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1')
-      assert_named_route &quot;#{shallow_path}/1/#{edit_action}.xml&quot;, &quot;formatted_edit_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1', :format =&gt; 'xml')
+      assert_named_route &quot;#{shallow_path}/1/#{edit_action}.xml&quot;, &quot;edit_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1', :format =&gt; 'xml')
 
       yield options[:options] if block_given?
     end
@@ -1189,12 +1189,12 @@ class ResourcesTest &lt; ActionController::TestCase
       name_prefix = options[:name_prefix]
 
       assert_named_route &quot;#{full_path}&quot;,          &quot;#{name_prefix}#{singleton_name}_path&quot;,                options[:options]
-      assert_named_route &quot;#{full_path}.xml&quot;,      &quot;formatted_#{name_prefix}#{singleton_name}_path&quot;,      options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}.xml&quot;,      &quot;#{name_prefix}#{singleton_name}_path&quot;,      options[:options].merge(:format =&gt; 'xml')
 
       assert_named_route &quot;#{full_path}/new&quot;,      &quot;new_#{name_prefix}#{singleton_name}_path&quot;,            options[:options]
-      assert_named_route &quot;#{full_path}/new.xml&quot;,  &quot;formatted_new_#{name_prefix}#{singleton_name}_path&quot;,  options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}/new.xml&quot;,  &quot;new_#{name_prefix}#{singleton_name}_path&quot;,  options[:options].merge(:format =&gt; 'xml')
       assert_named_route &quot;#{full_path}/edit&quot;,     &quot;edit_#{name_prefix}#{singleton_name}_path&quot;,           options[:options]
-      assert_named_route &quot;#{full_path}/edit.xml&quot;, &quot;formatted_edit_#{name_prefix}#{singleton_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}/edit.xml&quot;, &quot;edit_#{name_prefix}#{singleton_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
     end
 
     def assert_named_route(expected, route, options)</diff>
      <filename>actionpack/test/controller/resources_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -301,6 +301,41 @@ class UrlWriterTests &lt; ActionController::TestCase
     assert_generates(&quot;/image&quot;, :controller=&gt; :image)
   end
 
+  def test_named_routes_with_nil_keys
+    add_host!
+    ActionController::Routing::Routes.draw do |map|
+      map.main '', :controller =&gt; 'posts'
+      map.resources :posts
+      map.connect ':controller/:action/:id'
+    end
+    # We need to create a new class in order to install the new named route.
+    kls = Class.new { include ActionController::UrlWriter }
+    controller = kls.new
+    params = {:action =&gt; :index, :controller =&gt; :posts, :format =&gt; :xml}
+    assert_equal(&quot;http://www.basecamphq.com/posts.xml&quot;, controller.send(:url_for, params))    
+    params[:format] = nil
+    assert_equal(&quot;http://www.basecamphq.com/&quot;, controller.send(:url_for, params))    
+  ensure
+    ActionController::Routing::Routes.load!
+  end
+
+  def test_formatted_url_methods_are_deprecated
+    ActionController::Routing::Routes.draw do |map|
+      map.resources :posts
+    end
+    # We need to create a new class in order to install the new named route.
+    kls = Class.new { include ActionController::UrlWriter }
+    controller = kls.new
+    params = {:id =&gt; 1, :format =&gt; :xml}
+    assert_deprecated do
+      assert_equal(&quot;/posts/1.xml&quot;, controller.send(:formatted_post_path, params))    
+    end
+    assert_deprecated do
+      assert_equal(&quot;/posts/1.xml&quot;, controller.send(:formatted_post_path, 1, :xml))    
+    end
+  ensure
+    ActionController::Routing::Routes.load!
+  end
   private
     def extract_params(url)
       url.split('?', 2).last.split('&amp;')</diff>
      <filename>actionpack/test/controller/url_rewriter_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>6599dd907f87875045005c3754fc7fe75c130c3e</id>
    </parent>
  </parents>
  <author>
    <name>Aaron Batalion</name>
    <login>aaronbatalion</login>
    <email>aaron@hungrymachine.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/fef6c32afe2276dffa0347e25808a86e7a101af1</url>
  <id>fef6c32afe2276dffa0347e25808a86e7a101af1</id>
  <committed-date>2008-11-26T01:52:05-08:00</committed-date>
  <authored-date>2008-11-23T23:24:19-08:00</authored-date>
  <message>Added optimal formatted routes to rails, deprecating the formatted_* methods, and reducing routes creation by 50% [#1359 state:committed]

Signed-off-by: David Heinemeier Hansson &lt;david@loudthinking.com&gt;</message>
  <tree>42a43392f0e478e7b752bfd885a4e91b08828487</tree>
  <committer>
    <name>David Heinemeier Hansson</name>
    <login>dhh</login>
    <email>david@loudthinking.com</email>
  </committer>
</commit>
