Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8226: filter_speedup_filter_chain_ordering_trunk.patch

File filter_speedup_filter_chain_ordering_trunk.patch, 4.1 kB (added by skaes, 2 years ago)

bug fix for filter chain ordering

  • actionpack/test/controller/filters_test.rb

    old new  
    131131    before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true} 
    132132  end 
    133133 
     134  class EmptyFilterChainController < TestController 
     135    self.filter_chain.clear 
     136    def show 
     137      @action_executed = true 
     138      render :text => "yawp!" 
     139    end 
     140  end 
     141 
    134142  class PrependingController < TestController 
    135143    prepend_before_filter :wonderful_life 
    136144    # skip_before_filter :fire_flash 
     
    293301      end 
    294302  end 
    295303 
     304  class PrependingBeforeAndAfterController < ActionController::Base 
     305    prepend_before_filter :before_all 
     306    prepend_after_filter :after_all 
     307    before_filter :between_before_all_and_after_all 
     308 
     309    def before_all 
     310      @ran_filter ||= [] 
     311      @ran_filter << 'before_all' 
     312    end 
     313 
     314    def after_all 
     315      @ran_filter ||= [] 
     316      @ran_filter << 'after_all' 
     317    end 
     318 
     319    def between_before_all_and_after_all 
     320      @ran_filter ||= [] 
     321      @ran_filter << 'between_before_all_and_after_all' 
     322    end 
     323    def show 
     324      render :text => 'hello' 
     325    end 
     326  end 
     327 
     328  def test_empty_filter_chain 
     329    assert_equal 0, EmptyFilterChainController.filter_chain.size 
     330    assert test_process(EmptyFilterChainController).template.assigns['action_executed'] 
     331  end 
     332 
    296333  def test_added_filter_to_inheritance_graph 
    297334    assert_equal [ :ensure_login ], TestController.before_filters 
    298335  end 
     
    426463    end 
    427464  end 
    428465 
     466  def test_running_prepended_before_and_after_filter 
     467    assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length 
     468    response = test_process(PrependingBeforeAndAfterController) 
     469    assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"] 
     470  end 
     471 
    429472  def test_conditional_skipping_of_filters 
    430473    assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"] 
    431474    assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"] 
  • actionpack/lib/action_controller/filters.rb

    old new  
    527527        end 
    528528 
    529529        def find_filter_append_position(filters, filter_type) 
     530          # appending an after filter puts it at the end of the call chain 
     531          # before and around filters goe before the first after filter in the chain 
    530532          unless filter_type == :after 
    531533            filter_chain.each_with_index do |f,i| 
    532534              return i if f.after? 
     
    536538        end 
    537539 
    538540        def find_filter_prepend_position(filters, filter_type) 
     541          # prepending a before or around filter puts it at the front of the call chain 
     542          # after filters go before the first after filter in the chain 
    539543          if filter_type == :after 
    540544            filter_chain.each_with_index do |f,i| 
    541545              return i if f.after? 
    542546            end 
     547            return -1 
    543548          end 
    544549          return 0 
    545550        end 
     
    684689 
    685690      def call_filters(chain, index, nesting) 
    686691        # run before filters until we find an after filter or around filter 
    687         while true 
     692        while chain[index] 
    688693          filter, index = skip_excluded_filters(chain, index) 
    689           break unless filter 
     694          break unless filter # end of call chain reached 
    690695          case filter.type 
    691696          when :before 
    692697            # invoke before filter 
     
    710715        return index if aborted || nesting != 0 
    711716 
    712717        # run after filters, if any 
    713         while filter = chain[index] 
     718        while chain[index] 
    714719          filter, index = skip_excluded_filters(chain, index) 
     720          break unless filter 
    715721          case filter.type 
    716722          when :after 
    717723            filter.run(self)