diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_controller/resources.rb | 35 | ||||
-rw-r--r-- | actionpack/test/controller/resources_test.rb | 43 |
2 files changed, 47 insertions, 31 deletions
diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb index e8988aa737..3af21967df 100644 --- a/actionpack/lib/action_controller/resources.rb +++ b/actionpack/lib/action_controller/resources.rb @@ -42,7 +42,7 @@ module ActionController # # Read more about REST at http://en.wikipedia.org/wiki/Representational_State_Transfer module Resources - INHERITABLE_OPTIONS = :namespace, :shallow, :actions + INHERITABLE_OPTIONS = :namespace, :shallow class Resource #:nodoc: DEFAULT_ACTIONS = :index, :create, :new, :edit, :show, :update, :destroy @@ -119,7 +119,7 @@ module ActionController end def has_action?(action) - !DEFAULT_ACTIONS.include?(action) || @options[:actions].nil? || @options[:actions].include?(action) + !DEFAULT_ACTIONS.include?(action) || action_allowed?(action) end protected @@ -135,24 +135,29 @@ module ActionController end def set_allowed_actions - only = @options.delete(:only) - except = @options.delete(:except) + only, except = @options.values_at(:only, :except) + @allowed_actions ||= {} - if only && except - raise ArgumentError, 'Please supply either :only or :except, not both.' - elsif only == :all || except == :none - options[:actions] = DEFAULT_ACTIONS + if only == :all || except == :none + only = nil + except = [] elsif only == :none || except == :all - options[:actions] = [] - elsif only - options[:actions] = DEFAULT_ACTIONS & Array(only).map(&:to_sym) + only = [] + except = nil + end + + if only + @allowed_actions[:only] = Array(only).map(&:to_sym) elsif except - options[:actions] = DEFAULT_ACTIONS - Array(except).map(&:to_sym) - else - # leave options[:actions] alone + @allowed_actions[:except] = Array(except).map(&:to_sym) end end + def action_allowed?(action) + only, except = @allowed_actions.values_at(:only, :except) + (!only || only.include?(action)) && (!except || !except.include?(action)) + end + def set_prefixes @path_prefix = options.delete(:path_prefix) @name_prefix = options.delete(:name_prefix) @@ -403,8 +408,6 @@ module ActionController # # --> POST /posts/1/comments (maps to the CommentsController#create action) # # --> PUT /posts/1/comments/1 (fails) # - # The <tt>:only</tt> and <tt>:except</tt> options are inherited by any nested resource(s). - # # If <tt>map.resources</tt> is called with multiple resources, they all get the same options applied. # # Examples: diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 8dedeb23f6..ae2639d245 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -942,19 +942,6 @@ class ResourcesTest < ActionController::TestCase end end - def test_nested_resource_inherits_only_show_action - with_routing do |set| - set.draw do |map| - map.resources :products, :only => :show do |product| - product.resources :images - end - end - - assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images') - assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images') - end - end - def test_nested_resource_has_only_show_and_member_action with_routing do |set| set.draw do |map| @@ -971,7 +958,7 @@ class ResourcesTest < ActionController::TestCase end end - def test_nested_resource_ignores_only_option + def test_nested_resource_does_not_inherit_only_option with_routing do |set| set.draw do |map| map.resources :products, :only => :show do |product| @@ -984,7 +971,20 @@ class ResourcesTest < ActionController::TestCase end end - def test_nested_resource_ignores_except_option + def test_nested_resource_does_not_inherit_only_option_by_default + with_routing do |set| + set.draw do |map| + map.resources :products, :only => :show do |product| + product.resources :images + end + end + + assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destory], [], 'products/1/images') + assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images') + end + end + + def test_nested_resource_does_not_inherit_except_option with_routing do |set| set.draw do |map| map.resources :products, :except => :show do |product| @@ -997,6 +997,19 @@ class ResourcesTest < ActionController::TestCase end end + def test_nested_resource_does_not_inherit_except_option_by_default + with_routing do |set| + set.draw do |map| + map.resources :products, :except => :show do |product| + product.resources :images + end + end + + assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images') + assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images') + end + end + def test_default_singleton_restful_route_uses_get with_routing do |set| set.draw do |map| |