Ticket #7047: url_for_arrays_and_hashes_with_to_query_sorted.diff
| File url_for_arrays_and_hashes_with_to_query_sorted.diff, 6.7 kB (added by dkubb, 2 years ago) |
|---|
-
activesupport/lib/active_support/core_ext/hash/conversions.rb
old new 9 9 end 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 15 15 … … 46 46 end 47 47 48 48 def to_query(namespace = nil) 49 collect do |key, value|49 sort_by { |k,v| k.to_s }.collect do |key, value| 50 50 value.to_query(namespace ? "#{namespace}[#{key}]" : key) 51 51 end * '&' 52 52 end -
actionpack/test/controller/url_rewriter_test.rb
old new 56 56 u = @rewriter.rewrite(:only_path => false, :overwrite_params => {:list_page => 2}) 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 70 61 class UrlWriterTests < Test::Unit::TestCase … … 160 151 ensure 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][]' => 'prof' }.to_query 197 assert_equal params[3], { 'query[person][position][]' => 'art director' }.to_query 198 end 199 200 private 201 def extract_params(url) 202 url.split('?', 2).last.split('&') 203 end 204 164 205 end -
actionpack/test/controller/routing_test.rb
old new 1008 1008 end 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 1014 1014 def test_escape_spaces_build_query_string_selected_keys -
actionpack/lib/action_controller/routing.rb
old new 452 452 # is given (as an array), only the keys indicated will be used to build 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 || "" 458 (only_keys || hash.keys).sort_by(&:to_s).each do |key| 459 elements << hash[key].to_query(key) if hash[key] 460 end 461 462 elements.empty? ? '' : "?#{elements * '&'}" 473 463 end 474 464 475 465 # Write the real recognition implementation and then resend the message. 476 466 def recognize(path, environment={}) 477 467 write_recognition … … 545 535 end 546 536 nil 547 537 end 548 538 549 539 end 550 540 551 541 class Segment #:nodoc: … … 669 659 end 670 660 671 661 def extract_value 672 "#{local_name} = hash[:#{key}] #{"|| #{default.inspect}" if default}"662 "#{local_name} = hash[:#{key}] && hash[:#{key}].to_param #{"|| #{default.inspect}" if default}" 673 663 end 674 664 def value_check 675 665 if default # Then we know it won't be nil … … 1195 1185 # 1196 1186 # great fun, eh? 1197 1187 1198 options_as_params = options[:controller] ? { :action => "index" } : {} 1199 options.each do |k, value| 1200 options_as_params[k] = value.to_param 1201 end 1188 options_as_params = options.clone 1189 options_as_params[:action] ||= 'index' if options[:controller] 1190 options_as_params[:action] = options_as_params[:action].to_s if options_as_params[:action] 1202 1191 options_as_params 1203 1192 end 1204 1193