Changeset 6343
- Timestamp:
- 03/06/07 07:47:23 (2 years ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_controller/routing.rb (modified) (4 diffs)
- trunk/actionpack/test/controller/routing_test.rb (modified) (1 diff)
- trunk/actionpack/test/controller/url_rewriter_test.rb (modified) (2 diffs)
- trunk/activesupport/lib/active_support/core_ext/hash/conversions.rb (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r6342 r6343 1 1 *SVN* 2 3 * 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] 2 4 3 5 # Add a #dbman attr_reader for CGI::Session and make CGI::Session::CookieStore#generate_digest public so it's easy to generate digests trunk/actionpack/lib/action_controller/routing.rb
r6185 r6343 453 453 # the query string. The query string will correctly build array parameter 454 454 # values. 455 def build_query_string(hash, only_keys =nil)455 def build_query_string(hash, only_keys = nil) 456 456 elements = [] 457 457 458 only_keys ||= hash.keys 459 460 only_keys.each do |key| 461 value = hash[key] or next 462 key = CGI.escape key.to_s 463 if value.class == Array 464 key << '[]' 465 else 466 value = [ value ] 467 end 468 value.each { |val| elements << "#{key}=#{CGI.escape(val.to_param.to_s)}" } 469 end 470 471 query_string = "?#{elements.join("&")}" unless elements.empty? 472 query_string || "" 473 end 474 458 (only_keys || hash.keys).each do |key| 459 if value = hash[key] 460 elements << value.to_query(key) 461 end 462 end 463 464 elements.empty? ? '' : "?#{elements.sort * '&'}" 465 end 466 475 467 # Write the real recognition implementation and then resend the message. 476 468 def recognize(path, environment={}) … … 546 538 nil 547 539 end 548 540 549 541 end 550 542 … … 670 662 671 663 def extract_value 672 "#{local_name} = hash[:#{key}] #{"|| #{default.inspect}" if default}"664 "#{local_name} = hash[:#{key}] && hash[:#{key}].to_param #{"|| #{default.inspect}" if default}" 673 665 end 674 666 def value_check … … 1196 1188 # great fun, eh? 1197 1189 1198 options_as_params = options[:controller] ? { :action => "index" } : {} 1199 options.each do |k, value| 1200 options_as_params[k] = value.to_param 1201 end 1190 options_as_params = options.clone 1191 options_as_params[:action] ||= 'index' if options[:controller] 1192 options_as_params[:action] = options_as_params[:action].to_s if options_as_params[:action] 1202 1193 options_as_params 1203 1194 end trunk/actionpack/test/controller/routing_test.rb
r6231 r6343 1009 1009 1010 1010 def test_expand_array_build_query_string 1011 assert_equal '?x []=1&x[]=2', order_query_string(@route.build_query_string(:x => [1, 2]))1011 assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2])) 1012 1012 end 1013 1013 trunk/actionpack/test/controller/url_rewriter_test.rb
r6314 r6343 57 57 assert_equal 'http://test.host/search/list?list_page=2', u 58 58 end 59 60 private61 def split_query_string(str)62 [str[0].chr] + str[1..-1].split(/&/).sort63 end64 65 def assert_query_equal(q1, q2)66 assert_equal(split_query_string(q1), split_query_string(q2))67 end68 59 end 69 60 … … 161 152 ActionController::Routing::Routes.load! 162 153 end 163 154 155 def test_one_parameter 156 assert_equal('/c/a?param=val', 157 W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val') 158 ) 159 end 160 161 def test_two_parameters 162 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2') 163 params = extract_params(url) 164 assert_equal params[0], { :p1 => 'X1' }.to_query 165 assert_equal params[1], { :p2 => 'Y2' }.to_query 166 end 167 168 def test_hash_parameter 169 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'}) 170 params = extract_params(url) 171 assert_equal params[0], { 'query[category]' => 'prof' }.to_query 172 assert_equal params[1], { 'query[name]' => 'Bob' }.to_query 173 end 174 175 def test_array_parameter 176 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof']) 177 params = extract_params(url) 178 assert_equal params[0], { 'query[]' => 'Bob' }.to_query 179 assert_equal params[1], { 'query[]' => 'prof' }.to_query 180 end 181 182 def test_hash_recursive_parameters 183 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'}) 184 params = extract_params(url) 185 assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query 186 assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query 187 assert_equal params[2], { 'query[person][position]' => 'prof' }.to_query 188 end 189 190 def test_hash_recursive_and_array_parameters 191 url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'}) 192 assert_match %r(^/c/a/101), url 193 params = extract_params(url) 194 assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query 195 assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query 196 assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query 197 assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query 198 end 199 200 private 201 def extract_params(url) 202 url.split('?', 2).last.split('&') 203 end 204 164 205 end trunk/activesupport/lib/active_support/core_ext/hash/conversions.rb
r6148 r6343 10 10 11 11 def to_query(key) #:nodoc: 12 "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param || "")}"12 "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}" 13 13 end 14 14 end … … 16 16 class Array 17 17 def to_query(key) #:nodoc: 18 collect { |value| value.to_query("#{key}[]") } * '&'18 collect { |value| value.to_query("#{key}[]") }.sort * '&' 19 19 end 20 20 end … … 49 49 collect do |key, value| 50 50 value.to_query(namespace ? "#{namespace}[#{key}]" : key) 51 end * '&'51 end.sort * '&' 52 52 end 53 53