Ticket #4947: url_rewriter_patch2.diff
| File url_rewriter_patch2.diff, 4.1 kB (added by me@julik.nl, 4 years ago) |
|---|
-
test/controller/url_rewriter_test.rb
old new 10 10 def test_simple_build_query_string 11 11 assert_query_equal '?x=1&y=2', @rewriter.send(:build_query_string, :x => '1', :y => '2') 12 12 end 13 13 14 def test_convert_ints_build_query_string 14 15 assert_query_equal '?x=1&y=2', @rewriter.send(:build_query_string, :x => 1, :y => 2) 15 16 end 17 16 18 def test_escape_spaces_build_query_string 17 19 assert_query_equal '?x=hello+world&y=goodbye+world', @rewriter.send(:build_query_string, :x => 'hello world', :y => 'goodbye world') 18 20 end 21 19 22 def test_expand_array_build_query_string 20 23 assert_query_equal '?x[]=1&x[]=2', @rewriter.send(:build_query_string, :x => [1, 2]) 21 24 end … … 24 27 assert_query_equal '?x=hello+world', @rewriter.send(:build_query_string, {:x => 'hello world', :y => 'goodbye world'}, [:x]) 25 28 end 26 29 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 27 43 def test_overwrite_params 28 44 @params[:controller] = 'hi' 29 45 @params[:action] = 'bye' -
lib/action_controller/url_rewriter.rb
old new 49 49 end 50 50 51 51 # 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 = {} 57 57 only_keys ||= hash.keys 58 58 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))) 64 65 else 65 value = [ value]66 params[param_key] = hash[key] 66 67 end 67 value.each { |val| elements << "#{key}=#{Routing.extract_parameter_value(val)}" }68 68 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 72 87 end 73 88 end 74 89 end