From 0c8dd2cab6793973384f7320c2cb2b832ec38aff Mon Sep 17 00:00:00 2001
From: Michael Colavita <colavitam@gmail.com>
Date: Mon, 13 Jul 2015 13:48:10 -0400
Subject: :only and :except are now chained for routing resource(s)

Allow chaining the :only and :except options for routing resource(s).
Previously, the following yielded routes for both show and destroy:

resource :account, :only => [:show, :destroy], :except => :destroy

This now yields only the show action. This chaining can be useful for
passing optional :except options to code that makes use of the :only
option (e.g. for a gem with its own routing methods).
---
 actionpack/CHANGELOG.md                          |  9 +++++++++
 actionpack/lib/action_dispatch/routing/mapper.rb | 12 +++++++++---
 actionpack/test/controller/resources_test.rb     | 22 ++++++++++++++++++++++
 3 files changed, 40 insertions(+), 3 deletions(-)

(limited to 'actionpack')

diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 46856ffc5d..1c0c3c4e10 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,12 @@
+*   Allow chaining the :only and :except options for routing resource(s).
+
+        resource :account, :only => [:show, :destroy], :except => :destroy
+
+    This now yields only the show action. This chaining can be useful for passing optional :except
+    options to code that makes use of the :only option.
+
+    *Michael Colavita*
+
 *   Add ability to filter parameters based on parent keys.
 
         # matches {credit_card: {code: "xxxx"}}
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 7cfe4693c1..40e00b55c2 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1061,16 +1061,22 @@ module ActionDispatch
             end
           end
 
-          def actions
+          def available_actions
             if only = @options[:only]
               Array(only).map(&:to_sym)
-            elsif except = @options[:except]
-              default_actions - Array(except).map(&:to_sym)
             else
               default_actions
             end
           end
 
+          def actions
+            if except = @options[:except]
+              available_actions - Array(except).map(&:to_sym)
+            else
+              available_actions
+            end
+          end
+
           def name
             @as || @name
           end
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 5a279639cc..603d7848f9 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -838,6 +838,28 @@ class ResourcesTest < ActionController::TestCase
     end
   end
 
+  def test_resource_has_show_action_but_does_not_have_destroy_action
+    with_routing do |set|
+      set.draw do
+        resources :products, :only => [:show, :destroy], :except => :destroy
+      end
+
+      assert_resource_allowed_routes('products', {},                    { :id => '1' }, :show, [:index, :new, :create, :edit, :update, :destroy])
+      assert_resource_allowed_routes('products', { :format => 'xml' },  { :id => '1' }, :show, [:index, :new, :create, :edit, :update, :destroy])
+    end
+  end
+
+  def test_singleton_resource_has_show_action_but_does_not_have_destroy_action
+    with_routing do |set|
+      set.draw do
+        resource :account, :only => [:show, :destroy], :except => :destroy
+      end
+
+      assert_singleton_resource_allowed_routes('accounts', {},                    :show, [:new, :create, :edit, :update, :destroy])
+      assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' },  :show, [:new, :create, :edit, :update, :destroy])
+    end
+  end
+
   def test_resource_has_only_create_action_and_named_route
     with_routing do |set|
       set.draw do
-- 
cgit v1.2.3