Changeset 7834
- Timestamp:
- 10/11/07 05:56:58 (1 year ago)
- Files:
-
- branches/1-2-stable/actionpack/CHANGELOG (modified) (1 diff)
- branches/1-2-stable/actionpack/lib/action_controller/routing.rb (modified) (3 diffs)
- branches/1-2-stable/actionpack/test/controller/routing_test.rb (modified) (1 diff)
- branches/1-2-stable/actionpack/test/controller/url_rewriter_test.rb (modified) (2 diffs)
- branches/1-2-stable/activesupport/CHANGELOG (modified) (1 diff)
- branches/1-2-stable/activesupport/lib/active_support/core_ext/hash/conversions.rb (modified) (2 diffs)
- branches/1-2-stable/activesupport/test/core_ext/hash_ext_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/1-2-stable/actionpack/CHANGELOG
r7783 r7834 1 1 *SVN* 2 3 * Backport: allow array and hash query parameters. Array route parameters are converted/to/a/path as before. #6765, #7047, #7462 [bgipsy, Jeremy McAnally, Dan Kubb, brendan, Diego Algorta Casamayou] 2 4 3 5 * Fix in place editor's setter action with non-string fields. #7418 [Andreas] branches/1-2-stable/actionpack/lib/action_controller/routing.rb
r7713 r7834 452 452 # the query string. The query string will correctly build array parameter 453 453 # values. 454 def build_query_string(hash, only_keys =nil)454 def build_query_string(hash, only_keys = nil) 455 455 elements = [] 456 457 only_keys ||= hash.keys458 456 459 only_keys.each do |key| 460 value = hash[key] or next 461 key = CGI.escape key.to_s 462 if value.class == Array 463 key << '[]' 464 else 465 value = [ value ] 466 end 467 value.each { |val| elements << "#{key}=#{CGI.escape(val.to_param.to_s)}" } 468 end 469 470 query_string = "?#{elements.join("&")}" unless elements.empty? 471 query_string || "" 472 end 473 457 (only_keys || hash.keys).each do |key| 458 if value = hash[key] 459 elements << value.to_query(key) 460 end 461 end 462 elements.empty? ? '' : "?#{elements.sort * '&'}" 463 end 464 474 465 # Write the real recognition implementation and then resend the message. 475 466 def recognize(path, environment={}) … … 669 660 670 661 def extract_value 671 "#{local_name} = hash[:#{key}] #{"|| #{default.inspect}" if default}"662 "#{local_name} = hash[:#{key}] && hash[:#{key}].to_param #{"|| #{default.inspect}" if default}" 672 663 end 673 664 def value_check … … 1231 1222 # great fun, eh? 1232 1223 1233 options_as_params = options[:controller] ? { :action => "index" } : {} 1234 options.each do |k, value| 1235 options_as_params[k] = value.to_param 1236 end 1224 options_as_params = options.clone 1225 options_as_params[:action] ||= 'index' if options[:controller] 1226 options_as_params[:action] = options_as_params[:action].to_s if options_as_params[:action] 1237 1227 options_as_params 1238 1228 end branches/1-2-stable/actionpack/test/controller/routing_test.rb
r6677 r7834 947 947 948 948 def test_expand_array_build_query_string 949 assert_equal '?x []=1&x[]=2', order_query_string(@route.build_query_string(:x => [1, 2]))949 assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2])) 950 950 end 951 951 branches/1-2-stable/actionpack/test/controller/url_rewriter_test.rb
r6651 r7834 24 24 ) 25 25 end 26 27 private28 def split_query_string(str)29 [str[0].chr] + str[1..-1].split(/&/).sort30 end31 32 def assert_query_equal(q1, q2)33 assert_equal(split_query_string(q1), split_query_string(q2))34 end35 26 end 36 27 … … 124 115 ActionController::Routing::Routes.load! 125 116 end 126 117 118 def test_one_parameter 119 assert_equal('/c/a?param=val', 120 W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val') 121 ) 122 end 123 124 def test_two_parameters 125 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2') 126 params = extract_params(url) 127 assert_equal params[0], { :p1 => 'X1' }.to_query 128 assert_equal params[1], { :p2 => 'Y2' }.to_query 129 end 130 131 def test_hash_parameter 132 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'}) 133 params = extract_params(url) 134 assert_equal params[0], { 'query[category]' => 'prof' }.to_query 135 assert_equal params[1], { 'query[name]' => 'Bob' }.to_query 136 end 137 138 def test_array_parameter 139 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof']) 140 params = extract_params(url) 141 assert_equal params[0], { 'query[]' => 'Bob' }.to_query 142 assert_equal params[1], { 'query[]' => 'prof' }.to_query 143 end 144 145 def test_hash_recursive_parameters 146 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'}) 147 params = extract_params(url) 148 assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query 149 assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query 150 assert_equal params[2], { 'query[person][position]' => 'prof' }.to_query 151 end 152 153 def test_hash_recursive_and_array_parameters 154 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'}) 155 assert_match %r(^/c/a/101), url 156 params = extract_params(url) 157 assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query 158 assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query 159 assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query 160 assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query 161 end 162 163 private 164 def extract_params(url) 165 url.split('?', 2).last.split('&') 166 end 127 167 end branches/1-2-stable/activesupport/CHANGELOG
r7740 r7834 1 *SVN* 2 3 * Backport: allow array and hash query parameters. Array route parameters are converted/to/a/path as before. #6765, #7047, #7462 [bgipsy, Jeremy McAnally, Dan Kubb, brendan, Diego Algorta Casamayou] 4 5 1 6 *1.4.3* (October 4th, 2007) 2 7 branches/1-2-stable/activesupport/lib/active_support/core_ext/hash/conversions.rb
r7087 r7834 1 1 require 'date' 2 2 require 'xml_simple' 3 require 'cgi' 4 5 # Extensions needed for Hash#to_query 6 class Object 7 def to_param #:nodoc: 8 to_s 9 end 10 11 def to_query(key) #:nodoc: 12 "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}" 13 end 14 end 15 16 class Array 17 def to_query(key) #:nodoc: 18 collect { |value| value.to_query("#{key}[]") }.sort * '&' 19 end 20 end 3 21 4 22 # Locked down XmlSimple#xml_in_string … … 47 65 def self.included(klass) 48 66 klass.extend(ClassMethods) 67 end 68 69 def to_query(namespace = nil) 70 collect do |key, value| 71 value.to_query(namespace ? "#{namespace}[#{key}]" : key) 72 end.sort * '&' 49 73 end 50 74 branches/1-2-stable/activesupport/test/core_ext/hash_ext_test.rb
r5522 r7834 471 471 end 472 472 end 473 474 class QueryTest < Test::Unit::TestCase 475 def test_simple_conversion 476 assert_query_equal 'a=10', :a => 10 477 end 478 479 def test_cgi_escaping 480 assert_query_equal 'a%3Ab=c+d', 'a:b' => 'c d' 481 end 482 483 def test_nil_parameter_value 484 empty = Object.new 485 def empty.to_param; nil end 486 assert_query_equal 'a=', 'a' => empty 487 end 488 489 def test_nested_conversion 490 assert_query_equal 'person%5Bname%5D=Nicholas&person%5Blogin%5D=seckar', 491 :person => {:name => 'Nicholas', :login => 'seckar'} 492 end 493 494 def test_multiple_nested 495 assert_query_equal 'account%5Bperson%5D%5Bid%5D=20&person%5Bid%5D=10', 496 :person => {:id => 10}, :account => {:person => {:id => 20}} 497 end 498 499 def test_array_values 500 assert_query_equal 'person%5Bid%5D%5B%5D=10&person%5Bid%5D%5B%5D=20', 501 :person => {:id => [10, 20]} 502 end 503 504 private 505 def assert_query_equal(expected, actual, message = nil) 506 assert_equal expected.split('&').sort, actual.to_query.split('&').sort 507 end 508 end 509