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

Ticket #4947: url_rewriter_patch2.diff

File url_rewriter_patch2.diff, 4.1 kB (added by me@julik.nl, 4 years ago)

Patch v2

  • test/controller/url_rewriter_test.rb

    old new  
    1010  def test_simple_build_query_string 
    1111    assert_query_equal '?x=1&y=2', @rewriter.send(:build_query_string, :x => '1', :y => '2') 
    1212  end 
     13 
    1314  def test_convert_ints_build_query_string 
    1415    assert_query_equal '?x=1&y=2', @rewriter.send(:build_query_string, :x => 1, :y => 2) 
    1516  end 
     17 
    1618  def test_escape_spaces_build_query_string 
    1719    assert_query_equal '?x=hello+world&y=goodbye+world', @rewriter.send(:build_query_string, :x => 'hello world', :y => 'goodbye world') 
    1820  end 
     21   
    1922  def test_expand_array_build_query_string 
    2023    assert_query_equal '?x[]=1&x[]=2', @rewriter.send(:build_query_string, :x => [1, 2]) 
    2124  end 
     
    2427    assert_query_equal '?x=hello+world', @rewriter.send(:build_query_string, {:x => 'hello world', :y => 'goodbye world'}, [:x]) 
    2528  end 
    2629 
     30  def test_expand_params_into_parent_with_unescaped_parent_key 
     31    output = {"some key[a]" => 2, "some key[b]" => 3 } 
     32    assert_equal output, @rewriter.send(:build_query_string, {:a => 2, :b => 3}, nil, parent = "some key") 
     33  end 
     34   
     35  def test_expand_deeply_nested_params 
     36    assert_query_equal '?a=1&b=2&c[a]=4&c[b]=5', @rewriter.send(:build_query_string, {:a => 1, :b => 2, :c => {:a => 4, :b => 5}}) 
     37  end 
     38   
     39  def test_expand_hashes_within_arrays 
     40    assert_query_equal "?a=1&b=2&c[]=a4b5", @rewriter.send(:build_query_string, {:a => 1, :b => 2, :c => [{:a => 4, :b => 5}] }) 
     41  end 
     42   
    2743  def test_overwrite_params 
    2844    @params[:controller] = 'hi' 
    2945    @params[:action] = 'bye' 
  • lib/action_controller/url_rewriter.rb

    old new  
    4949      end 
    5050 
    5151      # Returns a query string with escaped keys and values from the passed hash. If the passed hash contains an "id" it'll 
    52       # be added as a path element instead of a regular parameter pair. 
    53       def build_query_string(hash, only_keys = nil) 
    54         elements = [] 
    55         query_string = "" 
    56  
     52      # be added as a path element instead of a regular parameter pair. If parent is passed, it will return an array of 
     53      # parameters, keyed into the parent. Both keys and values are escaped. It will expand nested hashes of unlimited depth, 
     54      # but will not expand the hashes within arrays. 
     55      def build_query_string (hash, only_keys = nil, parent = nil) 
     56        params = {} 
    5757        only_keys ||= hash.keys 
    5858         
    59         only_keys.each do |key| 
    60           value = hash[key]  
    61           key = CGI.escape key.to_s 
    62           if value.class == Array 
    63             key <<  '[]' 
     59        only_keys.each do | key | 
     60          value = hash[key] 
     61          param_key = parent ? ( parent + "[" + CGI.escape(key.to_s) + "]") : CGI.escape(key.to_s) 
     62          if hash[key].is_a?(Hash) 
     63            # We escape the parent key onle once to spare some cycles 
     64            params.merge!(build_query_string(hash[key], hash[key].keys, CGI.escape(param_key.to_s))) 
    6465          else 
    65             value = [ value
     66            params[param_key] = hash[key
    6667          end 
    67           value.each { |val| elements << "#{key}=#{Routing.extract_parameter_value(val)}" } 
    6868        end 
    69          
    70         query_string << ("?" + elements.join("&")) unless elements.empty? 
    71         query_string 
     69 
     70        if parent 
     71          # Pass the array of parameters up the stack 
     72          return params 
     73        else 
     74          query_string = '' 
     75          elements = [] 
     76          # Compact arrays first 
     77          params.each_pair do | key, value | 
     78            if value.is_a?(Array) 
     79              elements += value.collect { | element | "#{key}[]=#{Routing.extract_parameter_value(element)}" } 
     80            else 
     81              elements << ("#{key}=#{Routing.extract_parameter_value(value)}") 
     82            end 
     83          end 
     84          query_string << ("?" + elements.join("&")) unless elements.empty? 
     85          query_string 
     86        end 
    7287      end 
    7388  end 
    7489end