public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Add :only/:except options to map.resources

This allows people with huge numbers of resource routes to cut down on the 
memory consumption caused by the generated code.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#1215 state:committed]
Tom Stuart (author)
Wed Nov 12 03:00:17 -0800 2008
NZKoz (committer)
Wed Nov 12 03:57:58 -0800 2008
commit  44a3009ff068bf080de6764a8c884fbf0ceb920e
tree    cba216c7f8f1ac3fd330e4c494924c38e4d9aee7
parent  c65075feb6c4ce15582bc08411e6698d782249a7
...
42
43
44
 
 
45
 
 
46
47
48
...
57
58
59
 
60
61
62
...
113
114
115
 
 
 
 
116
117
118
...
125
126
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
129
130
...
353
354
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
357
358
...
478
479
480
481
 
482
483
484
...
495
496
497
498
 
499
500
501
...
507
508
509
510
 
511
512
513
...
522
523
524
525
 
526
527
528
...
531
532
533
534
535
 
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
 
 
553
554
555
556
557
 
558
559
560
561
562
563
564
565
566
567
 
 
 
 
 
 
568
 
 
569
570
571
...
574
575
576
577
578
579
580
581
582
 
583
584
585
586
587
588
589
590
591
592
593
594
 
 
 
595
596
597
598
599
600
601
602
603
604
 
 
 
 
 
 
 
 
 
 
 
 
 
605
606
607
...
42
43
44
45
46
47
48
49
50
51
52
...
61
62
63
64
65
66
67
...
118
119
120
121
122
123
124
125
126
127
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
...
530
531
532
 
533
534
535
536
...
547
548
549
 
550
551
552
553
...
559
560
561
 
562
563
564
565
...
574
575
576
 
577
578
579
580
...
583
584
585
 
 
586
587
588
589
590
591
592
 
593
594
595
596
597
598
 
 
 
 
599
600
601
602
603
 
 
604
605
606
607
608
609
 
 
 
 
 
610
611
612
613
614
615
616
617
618
619
620
621
...
624
625
626
 
 
627
628
629
 
630
631
632
633
634
 
 
 
 
 
 
 
 
635
636
637
638
639
 
 
 
 
 
 
 
 
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
0
@@ -42,7 +42,11 @@ module ActionController
0
   #
0
   # Read more about REST at http://en.wikipedia.org/wiki/Representational_State_Transfer
0
   module Resources
0
+    INHERITABLE_OPTIONS = :namespace, :shallow, :only, :except
0
+
0
     class Resource #:nodoc:
0
+      DEFAULT_ACTIONS = :index, :create, :new, :edit, :show, :update, :destroy
0
+
0
       attr_reader :collection_methods, :member_methods, :new_methods
0
       attr_reader :path_prefix, :name_prefix, :path_segment
0
       attr_reader :plural, :singular
0
@@ -57,6 +61,7 @@ module ActionController
0
 
0
         arrange_actions
0
         add_default_actions
0
+        set_allowed_actions
0
         set_prefixes
0
       end
0
 
0
@@ -113,6 +118,10 @@ module ActionController
0
         @singular.to_s == @plural.to_s
0
       end
0
 
0
+      def has_action?(action)
0
+        !DEFAULT_ACTIONS.include?(action) || action_allowed?(action)
0
+      end
0
+
0
       protected
0
         def arrange_actions
0
           @collection_methods = arrange_actions_by_methods(options.delete(:collection))
0
@@ -125,6 +134,30 @@ module ActionController
0
           add_default_action(new_methods, :get, :new)
0
         end
0
 
0
+        def set_allowed_actions
0
+          only, except = @options.values_at(:only, :except)
0
+          @allowed_actions ||= {}
0
+
0
+          if only == :all || except == :none
0
+            only = nil
0
+            except = []
0
+          elsif only == :none || except == :all
0
+            only = []
0
+            except = nil
0
+          end
0
+
0
+          if only
0
+            @allowed_actions[:only] = Array(only).map(&:to_sym)
0
+          elsif except
0
+            @allowed_actions[:except] = Array(except).map(&:to_sym)
0
+          end
0
+        end
0
+
0
+        def action_allowed?(action)
0
+          only, except = @allowed_actions.values_at(:only, :except)
0
+          (!only || only.include?(action)) && (!except || !except.include?(action))
0
+        end
0
+
0
         def set_prefixes
0
           @path_prefix = options.delete(:path_prefix)
0
           @name_prefix = options.delete(:name_prefix)
0
@@ -353,6 +386,25 @@ module ActionController
0
     #
0
     #   map.resources :users, :has_many => { :posts => :comments }, :shallow => true
0
     #
0
+    # * <tt>:only</tt> and <tt>:except</tt> - Specify which of the seven default actions should be routed to.
0
+    #
0
+    # <tt>:only</tt> and <tt>:except</tt> may be set to <tt>:all</tt>, <tt>:none</tt>, an action name or a
0
+    # list of action names. By default, routes are generated for all seven actions.
0
+    #
0
+    # For example:
0
+    #
0
+    #   map.resources :posts, :only => [:index, :show] do |post|
0
+    #     post.resources :comments, :except => [:update, :destroy]
0
+    #   end
0
+    #   # --> GET /posts (maps to the PostsController#index action)
0
+    #   # --> POST /posts (fails)
0
+    #   # --> GET /posts/1 (maps to the PostsController#show action)
0
+    #   # --> DELETE /posts/1 (fails)
0
+    #   # --> POST /posts/1/comments (maps to the CommentsController#create action)
0
+    #   # --> PUT /posts/1/comments/1 (fails)
0
+    #
0
+    # The <tt>:only</tt> and <tt>:except</tt> options are inherited by any nested resource(s).
0
+    #
0
     # If <tt>map.resources</tt> is called with multiple resources, they all get the same options applied.
0
     #
0
     # Examples:
0
@@ -478,7 +530,7 @@ module ActionController
0
           map_associations(resource, options)
0
 
0
           if block_given?
0
-            with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], :shallow => options[:shallow], &block)
0
+            with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
0
           end
0
         end
0
       end
0
@@ -495,7 +547,7 @@ module ActionController
0
           map_associations(resource, options)
0
 
0
           if block_given?
0
-            with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], :shallow => options[:shallow], &block)
0
+            with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
0
           end
0
         end
0
       end
0
@@ -507,7 +559,7 @@ module ActionController
0
         name_prefix = "#{options.delete(:name_prefix)}#{resource.nesting_name_prefix}"
0
 
0
         Array(options[:has_one]).each do |association|
0
-          resource(association, :path_prefix => path_prefix, :name_prefix => name_prefix, :namespace => options[:namespace], :shallow => options[:shallow])
0
+          resource(association, options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => path_prefix, :name_prefix => name_prefix))
0
         end
0
       end
0
 
0
@@ -522,7 +574,7 @@ module ActionController
0
             map_has_many_associations(resource, association, options)
0
           end
0
         when Symbol, String
0
-          resources(associations, :path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], :shallow => options[:shallow], :has_many => options[:has_many])
0
+          resources(associations, options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :has_many => options[:has_many]))
0
         else
0
         end
0
       end
0
@@ -531,41 +583,39 @@ module ActionController
0
         resource.collection_methods.each do |method, actions|
0
           actions.each do |action|
0
             [method].flatten.each do |m|
0
-              action_options = action_options_for(action, resource, m)
0
-              map_named_routes(map, "#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.path}#{resource.action_separator}#{action}", action_options)
0
+              map_resource_routes(map, resource, action, "#{resource.path}#{resource.action_separator}#{action}", "#{action}_#{resource.name_prefix}#{resource.plural}", m)
0
             end
0
           end
0
         end
0
       end
0
 
0
       def map_default_collection_actions(map, resource)
0
-        index_action_options = action_options_for("index", resource)
0
         index_route_name = "#{resource.name_prefix}#{resource.plural}"
0
 
0
         if resource.uncountable?
0
           index_route_name << "_index"
0
         end
0
 
0
-        map_named_routes(map, index_route_name, resource.path, index_action_options)
0
-
0
-        create_action_options = action_options_for("create", resource)
0
-        map_unnamed_routes(map, resource.path, create_action_options)
0
+        map_resource_routes(map, resource, :index, resource.path, index_route_name)
0
+        map_resource_routes(map, resource, :create, resource.path)
0
       end
0
 
0
       def map_default_singleton_actions(map, resource)
0
-        create_action_options = action_options_for("create", resource)
0
-        map_unnamed_routes(map, resource.path, create_action_options)
0
+        map_resource_routes(map, resource, :create, resource.path)
0
       end
0
 
0
       def map_new_actions(map, resource)
0
         resource.new_methods.each do |method, actions|
0
           actions.each do |action|
0
-            action_options = action_options_for(action, resource, method)
0
-            if action == :new
0
-              map_named_routes(map, "new_#{resource.name_prefix}#{resource.singular}", resource.new_path, action_options)
0
-            else
0
-              map_named_routes(map, "#{action}_new_#{resource.name_prefix}#{resource.singular}", "#{resource.new_path}#{resource.action_separator}#{action}", action_options)
0
+            route_path = resource.new_path
0
+            route_name = "new_#{resource.name_prefix}#{resource.singular}"
0
+
0
+            unless action == :new
0
+              route_path = "#{route_path}#{resource.action_separator}#{action}"
0
+              route_name = "#{action}_#{route_name}"
0
             end
0
+
0
+            map_resource_routes(map, resource, action, route_path, route_name, method)
0
           end
0
         end
0
       end
0
@@ -574,34 +624,32 @@ module ActionController
0
         resource.member_methods.each do |method, actions|
0
           actions.each do |action|
0
             [method].flatten.each do |m|
0
-              action_options = action_options_for(action, resource, m)
0
-
0
               action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
0
               action_path ||= Base.resources_path_names[action] || action
0
 
0
-              map_named_routes(map, "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action_path}", action_options)
0
+              map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m)
0
             end
0
           end
0
         end
0
 
0
-        show_action_options = action_options_for("show", resource)
0
-        map_named_routes(map, "#{resource.shallow_name_prefix}#{resource.singular}", resource.member_path, show_action_options)
0
-
0
-        update_action_options = action_options_for("update", resource)
0
-        map_unnamed_routes(map, resource.member_path, update_action_options)
0
-
0
-        destroy_action_options = action_options_for("destroy", resource)
0
-        map_unnamed_routes(map, resource.member_path, destroy_action_options)
0
+        map_resource_routes(map, resource, :show, resource.member_path, "#{resource.shallow_name_prefix}#{resource.singular}")
0
+        map_resource_routes(map, resource, :update, resource.member_path)
0
+        map_resource_routes(map, resource, :destroy, resource.member_path)
0
       end
0
 
0
-      def map_unnamed_routes(map, path_without_format, options)
0
-        map.connect(path_without_format, options)
0
-        map.connect("#{path_without_format}.:format", options)
0
-      end
0
-
0
-      def map_named_routes(map, name, path_without_format, options)
0
-        map.named_route(name, path_without_format, options)
0
-        map.named_route("formatted_#{name}", "#{path_without_format}.:format", options)
0
+      def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil)
0
+        if resource.has_action?(action)
0
+          action_options = action_options_for(action, resource, method)
0
+          formatted_route_path = "#{route_path}.:format"
0
+
0
+          if route_name
0
+            map.named_route(route_name, route_path, action_options)
0
+            map.named_route("formatted_#{route_name}", formatted_route_path, action_options)
0
+          else
0
+            map.connect(route_path, action_options)
0
+            map.connect(formatted_route_path, action_options)
0
+          end
0
+        end
0
       end
0
 
0
       def add_conditions_for(conditions, method)
...
14
15
16
 
 
17
18
19
...
776
777
778
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
779
780
781
...
979
980
981
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
982
983
984
...
14
15
16
17
18
19
20
21
...
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
...
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
0
@@ -14,6 +14,8 @@ class LogosController < ResourcesController; end
0
 
0
 class AccountsController <  ResourcesController; end
0
 class AdminController   <  ResourcesController; end
0
+class ProductsController < ResourcesController; end
0
+class ImagesController < ResourcesController; end
0
 
0
 module Backoffice
0
   class ProductsController < ResourcesController; end
0
@@ -776,6 +778,121 @@ class ResourcesTest < Test::Unit::TestCase
0
     end
0
   end
0
 
0
+  def test_resource_has_only_show_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resources :products, :only => :show
0
+      end
0
+
0
+      assert_resource_allowed_routes('products', {},                    { :id => '1' }, :show, [:index, :new, :create, :edit, :update, :destroy])
0
+      assert_resource_allowed_routes('products', { :format => 'xml' },  { :id => '1' }, :show, [:index, :new, :create, :edit, :update, :destroy])
0
+    end
0
+  end
0
+
0
+  def test_singleton_resource_has_only_show_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resource :account, :only => :show
0
+      end
0
+
0
+      assert_singleton_resource_allowed_routes('accounts', {},                    :show, [:index, :new, :create, :edit, :update, :destroy])
0
+      assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' },  :show, [:index, :new, :create, :edit, :update, :destroy])
0
+    end
0
+  end
0
+
0
+  def test_resource_does_not_have_destroy_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resources :products, :except => :destroy
0
+      end
0
+
0
+      assert_resource_allowed_routes('products', {},                    { :id => '1' }, [:index, :new, :create, :show, :edit, :update], :destroy)
0
+      assert_resource_allowed_routes('products', { :format => 'xml' },  { :id => '1' }, [:index, :new, :create, :show, :edit, :update], :destroy)
0
+    end
0
+  end
0
+
0
+  def test_singleton_resource_does_not_have_destroy_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resource :account, :except => :destroy
0
+      end
0
+
0
+      assert_singleton_resource_allowed_routes('accounts', {},                    [:new, :create, :show, :edit, :update], :destroy)
0
+      assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' },  [:new, :create, :show, :edit, :update], :destroy)
0
+    end
0
+  end
0
+
0
+  def test_resource_has_only_collection_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resources :products, :except => :all, :collection => { :sale => :get }
0
+      end
0
+
0
+      assert_resource_allowed_routes('products', {},                    { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
0
+      assert_resource_allowed_routes('products', { :format => 'xml' },  { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
0
+
0
+      assert_recognizes({ :controller => 'products', :action => 'sale' },                   :path => 'products/sale',     :method => :get)
0
+      assert_recognizes({ :controller => 'products', :action => 'sale', :format => 'xml' }, :path => 'products/sale.xml', :method => :get)
0
+    end
0
+  end
0
+
0
+  def test_resource_has_only_member_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resources :products, :except => :all, :member => { :preview => :get }
0
+      end
0
+
0
+      assert_resource_allowed_routes('products', {},                    { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
0
+      assert_resource_allowed_routes('products', { :format => 'xml' },  { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
0
+
0
+      assert_recognizes({ :controller => 'products', :action => 'preview', :id => '1' },                    :path => 'products/1/preview',      :method => :get)
0
+      assert_recognizes({ :controller => 'products', :action => 'preview', :id => '1', :format => 'xml' },  :path => 'products/1/preview.xml',  :method => :get)
0
+    end
0
+  end
0
+
0
+  def test_singleton_resource_has_only_member_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resource :account, :except => :all, :member => { :signup => :get }
0
+      end
0
+
0
+      assert_singleton_resource_allowed_routes('accounts', {},                    [], [:new, :create, :show, :edit, :update, :destroy])
0
+      assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' },  [], [:new, :create, :show, :edit, :update, :destroy])
0
+
0
+      assert_recognizes({ :controller => 'accounts', :action => 'signup' },                   :path => 'account/signup',      :method => :get)
0
+      assert_recognizes({ :controller => 'accounts', :action => 'signup', :format => 'xml' }, :path => 'account/signup.xml',  :method => :get)
0
+    end
0
+  end
0
+
0
+  def test_nested_resource_inherits_only_show_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resources :products, :only => :show do |product|
0
+          product.resources :images
0
+        end
0
+      end
0
+
0
+      assert_resource_allowed_routes('images', { :product_id => '1' },                    { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
0
+      assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' },  { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
0
+    end
0
+  end
0
+
0
+  def test_nested_resource_has_only_show_and_member_action
0
+    with_routing do |set|
0
+      set.draw do |map|
0
+        map.resources :products, :only => [:index, :show] do |product|
0
+          product.resources :images, :member => { :thumbnail => :get }, :only => :show
0
+        end
0
+      end
0
+
0
+      assert_resource_allowed_routes('images', { :product_id => '1' },                    { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
0
+      assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' },  { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
0
+
0
+      assert_recognizes({ :controller => 'images', :action => 'thumbnail', :product_id => '1', :id => '2' },                    :path => 'products/1/images/2/thumbnail', :method => :get)
0
+      assert_recognizes({ :controller => 'images', :action => 'thumbnail', :product_id => '1', :id => '2', :format => 'jpg' },  :path => 'products/1/images/2/thumbnail.jpg', :method => :get)
0
+    end
0
+  end
0
+
0
   protected
0
     def with_restful_routing(*args)
0
       with_routing do |set|
0
@@ -979,6 +1096,51 @@ class ResourcesTest < Test::Unit::TestCase
0
       end
0
     end
0
 
0
+    def assert_resource_allowed_routes(controller, options, shallow_options, allowed, not_allowed, path = controller)
0
+      shallow_path = "#{path}/#{shallow_options[:id]}"
0
+      format = options[:format] && ".#{options[:format]}"
0
+      options.merge!(:controller => controller)
0
+      shallow_options.merge!(options)
0
+
0
+      assert_whether_allowed(allowed, not_allowed, options,         'index',    "#{path}#{format}",               :get)
0
+      assert_whether_allowed(allowed, not_allowed, options,         'new',      "#{path}/new#{format}",           :get)
0
+      assert_whether_allowed(allowed, not_allowed, options,         'create',   "#{path}#{format}",               :post)
0
+      assert_whether_allowed(allowed, not_allowed, shallow_options, 'show',     "#{shallow_path}#{format}",       :get)
0
+      assert_whether_allowed(allowed, not_allowed, shallow_options, 'edit',     "#{shallow_path}/edit#{format}",  :get)
0
+      assert_whether_allowed(allowed, not_allowed, shallow_options, 'update',   "#{shallow_path}#{format}",       :put)
0
+      assert_whether_allowed(allowed, not_allowed, shallow_options, 'destroy',  "#{shallow_path}#{format}",       :delete)
0
+    end
0
+
0
+    def assert_singleton_resource_allowed_routes(controller, options, allowed, not_allowed, path = controller.singularize)
0
+      format = options[:format] && ".#{options[:format]}"
0
+      options.merge!(:controller => controller)
0
+
0
+      assert_whether_allowed(allowed, not_allowed, options, 'new',      "#{path}/new#{format}",   :get)
0
+      assert_whether_allowed(allowed, not_allowed, options, 'create',   "#{path}#{format}",       :post)
0
+      assert_whether_allowed(allowed, not_allowed, options, 'show',     "#{path}#{format}",       :get)
0
+      assert_whether_allowed(allowed, not_allowed, options, 'edit',     "#{path}/edit#{format}",  :get)
0
+      assert_whether_allowed(allowed, not_allowed, options, 'update',   "#{path}#{format}",       :put)
0
+      assert_whether_allowed(allowed, not_allowed, options, 'destroy',  "#{path}#{format}",       :delete)
0
+    end
0
+
0
+    def assert_whether_allowed(allowed, not_allowed, options, action, path, method)
0
+      action = action.to_sym
0
+      options = options.merge(:action => action.to_s)
0
+      path_options = { :path => path, :method => method }
0
+
0
+      if Array(allowed).include?(action)
0
+        assert_recognizes options, path_options
0
+      elsif Array(not_allowed).include?(action)
0
+        assert_not_recognizes options, path_options
0
+      end
0
+    end
0
+
0
+    def assert_not_recognizes(expected_options, path)
0
+      assert_raise ActionController::RoutingError, ActionController::MethodNotAllowed, Test::Unit::AssertionFailedError do
0
+        assert_recognizes(expected_options, path)
0
+      end
0
+    end
0
+
0
     def distinct_routes? (r1, r2)
0
       if r1.conditions == r2.conditions and r1.requirements == r2.requirements then
0
         if r1.segments.collect(&:to_s) == r2.segments.collect(&:to_s) then

Comments

adkron Wed Nov 12 07:01:43 -0800 2008

woot. I was working on this, but now I can stop.

samgranieri Wed Nov 12 12:36:52 -0800 2008

This is fantastic! I hope this makes it into 2.2

joshuaclayton Wed Nov 12 13:40:46 -0800 2008

I would love to see this included in 2.2. Totally awesome.

adkron Wed Nov 12 17:00:21 -0800 2008

+1 for 2.2 inclusion

sob Wed Nov 12 18:07:04 -0800 2008

+1 for 2.2 inclusion as well. This is sweet.

jonnii Wed Nov 12 21:28:40 -0800 2008

+1 for 2.2 inclusion.

NZKoz Thu Nov 13 00:59:43 -0800 2008

Guys, this is still the 2.2 branch, it’s going in. ;)

zargony Thu Nov 13 03:39:35 -0800 2008

nice :)

garner Thu Nov 13 04:19:36 -0800 2008

+1 for 2.2 inclusion

joshsusser Thu Nov 13 05:09:14 -0800 2008

I’m all for the feature (been wanting it for ages), but I’d favor holding it to 2.2.1. Maintaining a feature freeze during a release cycle is important for the quality and stability of a release, and relaxing the discipline of a freeze for a shiny object is going to get you in trouble eventually.

andrzejsliwa Thu Nov 13 05:54:55 -0800 2008

+1 for 2.2 inclusion, great job

alloy Thu Nov 13 06:47:36 -0800 2008

I have to agree with joshsusser on this.

NZKoz Thu Nov 13 07:40:03 -0800 2008

We want it in for 2.2 final, if you think we should do another RC with it included, then we can do that. However it seems relatively harmless.

Pipe up on the ticket if you feel strongly about it. There’s an enhancement to come it seems

joshsusser Thu Nov 13 09:16:01 -0800 2008

There have probably been enough changes since RC1 to merit an RC2, especially since there have been some feature additions. And I notice there was an issue with removing index and show helpers, which is a good indication this change needs some time to bake.

sbfaulkner Thu Nov 13 10:48:01 -0800 2008

lol… apparently I was ahead of my time, I was shot down for suggesting this feature – which lead to me adding “shallow” nesting instead… oh well, now we have both

NZKoz Thu Nov 13 11:14:14 -0800 2008

@sbfaulkner: heh, yeah. Specific numbers on the memory usage made me change my mind.

@joshsusser: Indeed, this particular changeset is only intended for people looking to cut down on memory usage with thousands of routes. I just tested with my app and it was a tiny tiny difference.

We’ll do an RC2 and keep it ‘frozen’ barring surprises.

lifo Fri Jan 30 11:41:17 -0800 2009

Adding a blank space.