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

Ticket #7047: url_for_arrays_and_hashes_with_to_query.diff

File url_for_arrays_and_hashes_with_to_query.diff, 5.3 kB (added by bgipsy, 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 
  • actionpack/test/controller/url_rewriter_test.rb

    old new  
    160160  ensure 
    161161    ActionController::Routing::Routes.load! 
    162162  end 
    163    
     163 
     164  def test_one_parameter 
     165    assert_equal('/c/a?param=val', 
     166      W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val') 
     167    ) 
     168  end 
     169 
     170  def test_two_parameters 
     171    url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2') 
     172    params = extract_params(url) 
     173    assert params.include?('p1=X1') 
     174    assert params.include?('p2=Y2') 
     175  end 
     176 
     177  def test_hash_parameter 
     178    url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'}) 
     179    params = extract_params(url) 
     180    assert params.include?(CGI.escape('query[name]') + '=Bob') 
     181    assert params.include?(CGI.escape('query[category]') + '=prof') 
     182  end 
     183 
     184  def test_array_parameter 
     185    url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof']) 
     186    params = extract_params(url) 
     187    assert params.include?(CGI.escape('query[]') + '=Bob') 
     188    assert params.include?(CGI.escape('query[]') + '=prof') 
     189  end 
     190 
     191  def test_hash_recursive_parameters 
     192    url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'}) 
     193    params = extract_params(url) 
     194    assert params.include?(CGI.escape('query[person][name]') + '=Bob') 
     195    assert params.include?(CGI.escape('query[person][position]') + '=prof') 
     196    assert params.include?(CGI.escape('query[hobby]') + '=piercing') 
     197  end 
     198 
     199  def test_hash_recursive_and_array_parameters 
     200    url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'}) 
     201    assert_match %r(^/c/a/101), url 
     202    params = extract_params(url) 
     203    assert params.include?(CGI.escape('query[person][name]') + '=Bob') 
     204    assert params.include?(CGI.escape('query[person][position][]') + '=prof') 
     205    assert params.include?(CGI.escape('query[person][position][]') + '=' + CGI.escape('art director')) 
     206    assert params.include?(CGI.escape('query[hobby]') + '=piercing') 
     207  end 
     208 
     209  private 
     210 
     211  def extract_params(url) 
     212    path, params = url.split('?', 2) 
     213    params.split('&') 
     214  end 
     215 
    164216end 
  • 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).each do |key| 
     459          elements << hash[key].to_query(key) if hash[key] 
     460        end 
     461 
     462        elements.empty? ? '' : ("?" + elements.join("&")) 
    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