Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added :only and :except controls to skip_before/after_filter just lik…

…e for when you add filters [DHH]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3504 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 2504982945828d24c9b799c408d71576508b4c15 1 parent 2bf3fa0
@dhh dhh authored
View
2  actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Added :only and :except controls to skip_before/after_filter just like for when you add filters [DHH]
+
* Ensure that the instance variables are copied to the template when performing render :update. [Nicholas Seckar]
* Add the ability to call JavaScriptGenerator methods from helpers called in update blocks. [Sam Stephenson] Example:
View
24 actionpack/lib/action_controller/filters.rb
@@ -251,18 +251,34 @@ def prepend_around_filter(*filters)
# Removes the specified filters from the +before+ filter chain. Note that this only works for skipping method-reference
# filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out
# of many sub-controllers need a different hierarchy.
+ #
+ # You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
+ # just like when you apply the filters.
def skip_before_filter(*filters)
- for filter in filters.flatten
- write_inheritable_attribute("before_filters", read_inheritable_attribute("before_filters") - [ filter ])
+ if conditions = extract_conditions!(filters)
+ conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
+ add_action_conditions(filters, conditions)
+ else
+ for filter in filters.flatten
+ write_inheritable_attribute("before_filters", read_inheritable_attribute("before_filters") - [ filter ])
+ end
end
end
# Removes the specified filters from the +after+ filter chain. Note that this only works for skipping method-reference
# filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out
# of many sub-controllers need a different hierarchy.
+ #
+ # You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
+ # just like when you apply the filters.
def skip_after_filter(*filters)
- for filter in filters.flatten
- write_inheritable_attribute("after_filters", read_inheritable_attribute("after_filters") - [ filter ])
+ if conditions = extract_conditions!(filters)
+ conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
+ add_action_conditions(filters, conditions)
+ else
+ for filter in filters.flatten
+ write_inheritable_attribute("after_filters", read_inheritable_attribute("after_filters") - [ filter ])
+ end
end
end
View
28 actionpack/test/controller/filters_test.rb
@@ -3,6 +3,7 @@
class FilterTest < Test::Unit::TestCase
class TestController < ActionController::Base
before_filter :ensure_login
+ after_filter :clean_up
def show
render :inline => "ran action"
@@ -13,6 +14,11 @@ def ensure_login
@ran_filter ||= []
@ran_filter << "ensure_login"
end
+
+ def clean_up
+ @ran_after_filter ||= []
+ @ran_after_filter << "clean_up"
+ end
end
class RenderingController < ActionController::Base
@@ -108,6 +114,20 @@ def wonderful_life
end
end
+ class ConditionalSkippingController < TestController
+ skip_before_filter :ensure_login, :only => [ :login ]
+ skip_after_filter :clean_up, :only => [ :login ]
+
+ def login
+ render :inline => "ran action"
+ end
+
+ def change_password
+ render :inline => "ran action"
+ end
+ end
+
+
class ProcController < PrependingController
before_filter(proc { |c| c.assigns["ran_proc_filter"] = true })
end
@@ -343,6 +363,14 @@ def test_dynamic_dispatch
end
end
+ def test_conditional_skipping_of_filters
+ assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"]
+ assert_equal %w( ensure_login ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"]
+
+ assert_nil test_process(ConditionalSkippingController, "login").template.controller.instance_variable_get("@ran_after_filter")
+ assert_equal %w( clean_up ), test_process(ConditionalSkippingController, "change_password").template.controller.instance_variable_get("@ran_after_filter")
+ end
+
private
def test_process(controller, action = "show")
request = ActionController::TestRequest.new
Please sign in to comment.
Something went wrong with that request. Please try again.