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

Ticket #9030: indifferent.diff

File indifferent.diff, 3.5 kB (added by jdrowell, 1 year ago)

Fixes interaction between HashWithIndifferentAccess and UrlEncodedPairParser and adds test

  • activesupport/lib/active_support/core_ext/hash/indifferent_access.rb

    old new  
    7979      when Hash 
    8080        value.with_indifferent_access 
    8181      when Array 
    82         value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e } 
     82        # don't do collect() because we need to be sure the object_id doesn't change 
     83        value.each_index do |i| 
     84          value[i] = value[i].with_indifferent_access if value[i].is_a?(Hash) 
     85        end 
     86        value 
    8387      else 
    8488        value 
    8589      end 
     
    9195    module Hash #:nodoc: 
    9296      module IndifferentAccess #:nodoc: 
    9397        def with_indifferent_access 
     98          return self if self.is_a?(HashWithIndifferentAccess) 
     99 
    94100          hash = HashWithIndifferentAccess.new(self) 
    95101          hash.default = self.default 
    96102          hash 
  • actionpack/test/controller/request_test.rb

    old new  
    410410    ) 
    411411  end 
    412412 
     413  def test_deep_query_string_lots_of_arrays_and_hashes 
     414    assert_equal( 
     415      {"a" => {"b" => [{"c" => {"d" => ["1"]}}, {"c" => {"d" => ["2"]}}, {"c" => {"d" => ["3"]}}]}}, 
     416      ActionController::AbstractRequest.parse_query_parameters('a[b][][c][d][]=1&a[b][][c][d][]=2&a[b][][c][d][]=3') 
     417    ) 
     418  end 
     419 
    413420  def test_query_string_with_nil 
    414421    assert_equal( 
    415422      { "action" => "create_customer", "full_name" => ''}, 
  • actionpack/lib/action_controller/request.rb

    old new  
    574574 
    575575    def initialize(pairs = []) 
    576576      super('') 
    577       @result = {} 
     577      @result = {}.with_indifferent_access 
    578578      pairs.each { |key, value| parse(key, value) } 
    579579    end 
    580580 
     
    584584    # Parse the query string 
    585585    def parse(key, value) 
    586586      self.string = key 
    587       @top, @parent = result, nil 
     587      @top, @parent = @result, nil 
    588588 
    589589      # First scan the bare key 
    590590      key = scan(KEY_REGEXP) or return 
     
    604604      # After we see a key, we must look ahead to determine our next action. Cases: 
    605605      # 
    606606      #   [] follows the key. Then the value must be an array. 
    607       #   = follows the key. (A value comes next) 
    608       #   & or the end of string follows the key. Then the key is a flag. 
    609       #   otherwise, a hash follows the key. 
     607      #   [? follows the key. Then the value must be an hash. 
     608      #   otherwise, we're done (or the format is invalid -- not handled) 
    610609      def post_key_check(key) 
    611610        if scan(/\[\]/) # a[b][] indicates that b is an array 
    612611          container(key, Array) 
    613612          nil 
    614613        elsif check(/\[[^\]]/) # a[b] indicates that a is a hash 
    615           container(key, Hash) 
     614          container(key, HashWithIndifferentAccess)  
    616615          nil 
    617616        else # End of key? We do nothing. 
    618617          key 
     
    634633 
    635634      # Bind a key (which may be nil for items in an array) to the provided value. 
    636635      def bind(key, value) 
    637         if top.is_a? Array 
     636        if top.is_a?(Array) 
    638637          if key 
    639638            if top[-1].is_a?(Hash) && ! top[-1].key?(key) 
    640639              top[-1][key] = value