From a6106e4ec645c0dc799ce7666d2a28b46ea6126d Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 4 Nov 2005 19:42:22 +0000 Subject: Added skip_before_filter/skip_after_filter for easier control of the filter chain in inheritance hierachies [DHH] Added short-hand to assert_tag so assert_tag :tag => "span" can be written as assert_tag "span" [DHH] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2873 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/lib/action_controller/assertions.rb | 13 ++++++++- actionpack/lib/action_controller/filters.rb | 37 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_controller') diff --git a/actionpack/lib/action_controller/assertions.rb b/actionpack/lib/action_controller/assertions.rb index 952cc683b2..ccc09972ee 100644 --- a/actionpack/lib/action_controller/assertions.rb +++ b/actionpack/lib/action_controller/assertions.rb @@ -221,6 +221,15 @@ module Test #:nodoc: # # assert that there is a "span" tag # assert_tag :tag => "span" # + # # assert that there is a "span" tag with id="x" + # assert_tag :tag => "span", :attributes => { :id => "x" } + # + # # assert that there is a "span" tag using the short-hand + # assert_tag :span + # + # # assert that there is a "span" tag with id="x" using the short-hand + # assert_tag :span, :attributes => { :id => "x" } + # # # assert that there is a "span" inside of a "div" # assert_tag :tag => "span", :parent => { :tag => "div" } # @@ -248,8 +257,9 @@ module Test #:nodoc: # :attributes => { :class => "enum" } }, # :descendant => { :tag => "span", # :child => /hello world/ } - def assert_tag(opts) + def assert_tag(*opts) clean_backtrace do + opts = opts.size > 1 ? opts.last.merge({ :tag => opts.first.to_s }) : opts.first tag = find_tag(opts) assert tag, "expected tag, but no tag found matching #{opts.inspect} in:\n#{@response.body.inspect}" end @@ -259,6 +269,7 @@ module Test #:nodoc: # exist. (See #assert_tag for a full discussion of the syntax.) def assert_no_tag(opts) clean_backtrace do + opts = opts.size > 1 ? opts.last.merge({ :tag => opts.first.to_s }) : opts.first tag = find_tag(opts) assert !tag, "expected no tag, but found tag matching #{opts.inspect} in:\n#{@response.body.inspect}" end diff --git a/actionpack/lib/action_controller/filters.rb b/actionpack/lib/action_controller/filters.rb index 6bbb91ae8b..3f712629db 100644 --- a/actionpack/lib/action_controller/filters.rb +++ b/actionpack/lib/action_controller/filters.rb @@ -127,6 +127,25 @@ module ActionController #:nodoc: # end # end # + # == Filter chain skipping + # + # Some times its convenient to specify a filter chain in a superclass that'll hold true for the majority of the + # subclasses, but not necessarily all of them. The subclasses that behave in exception can then specify which filters + # they would like to be relieved of. Examples + # + # class ApplicationController < ActionController::Base + # before_filter :authenticate + # end + # + # class WeblogController < ApplicationController + # # will run the :authenticate filter + # end + # + # class SignupController < ActionController::Base + # # will not run the :authenticate filter + # skip_before_filter :authenticate + # end + # # == Filter conditions # # Filters can be limited to run for only specific actions. This can be expressed either by listing the actions to @@ -229,6 +248,24 @@ module ActionController #:nodoc: # Short-hand for append_around_filter since that's the most common of the two. alias :around_filter :append_around_filter + # 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. + def skip_before_filter(*filters) + for filter in filters.flatten + write_inheritable_attribute("before_filters", read_inheritable_attribute("before_filters") - [ filter ]) + 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. + def skip_after_filter(*filters) + for filter in filters.flatten + write_inheritable_attribute("after_filters", read_inheritable_attribute("after_filters") - [ filter ]) + end + end + # Returns all the before filters for this class and all its ancestors. def before_filters #:nodoc: read_inheritable_attribute("before_filters") -- cgit v1.2.3