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

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  
    99  end 
    1010 
    1111  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)}" 
    1313  end 
    1414end 
    1515 
     
    4646        end 
    4747 
    4848        def to_query(namespace = nil) 
    49           collect do |key, value| 
     49          sort_by { |k,v| k.to_s }.collect do |key, value| 
    5050            value.to_query(namespace ? "#{namespace}[#{key}]" : key) 
    5151          end * '&' 
    5252        end 
  • actionpack/test/controller/url_rewriter_test.rb

    old new  
    5656    u = @rewriter.rewrite(:only_path => false, :overwrite_params => {:list_page => 2}) 
    5757    assert_equal 'http://test.host/search/list?list_page=2', u 
    5858  end 
    59  
    60   private 
    61     def split_query_string(str) 
    62       [str[0].chr] + str[1..-1].split(/&/).sort 
    63     end 
    64    
    65     def assert_query_equal(q1, q2) 
    66       assert_equal(split_query_string(q1), split_query_string(q2)) 
    67     end 
    6859end 
    6960 
    7061class UrlWriterTests < Test::Unit::TestCase 
     
    160151  ensure 
    161152    ActionController::Routing::Routes.load! 
    162153  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 
    164205end 
  • actionpack/test/controller/routing_test.rb

    old new  
    10081008  end 
    10091009 
    10101010  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])) 
    10121012  end 
    10131013 
    10141014  def test_escape_spaces_build_query_string_selected_keys 
  • actionpack/lib/action_controller/routing.rb

    old new  
    452452      # is given (as an array), only the keys indicated will be used to build 
    453453      # the query string. The query string will correctly build array parameter 
    454454      # values. 
    455       def build_query_string(hash, only_keys=nil) 
     455      def build_query_string(hash, only_keys = nil) 
    456456        elements = [] 
    457457 
    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 * '&'}" 
    473463      end 
    474    
     464 
    475465      # Write the real recognition implementation and then resend the message. 
    476466      def recognize(path, environment={}) 
    477467        write_recognition 
     
    545535        end 
    546536        nil 
    547537      end 
    548    
     538 
    549539    end 
    550540 
    551541    class Segment #:nodoc: 
     
    669659      end 
    670660   
    671661      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}" 
    673663      end 
    674664      def value_check 
    675665        if default # Then we know it won't be nil 
     
    11951185        # 
    11961186        # great fun, eh? 
    11971187 
    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] 
    12021191        options_as_params 
    12031192      end 
    12041193