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

Changeset 6343

Show
Ignore:
Timestamp:
03/06/07 07:47:23 (2 years ago)
Author:
bitsweat
Message:

Allow array and hash query parameters. Array route parameters are converted/to/a/path as before. References #6765, #7462. Closes #7047.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r6342 r6343  
    11*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] 
    24 
    35# 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  
    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 || "" 
    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 
    475467      # Write the real recognition implementation and then resend the message. 
    476468      def recognize(path, environment={}) 
     
    546538        nil 
    547539      end 
    548    
     540 
    549541    end 
    550542 
     
    670662   
    671663      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}" 
    673665      end 
    674666      def value_check 
     
    11961188        # great fun, eh? 
    11971189 
    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] 
    12021193        options_as_params 
    12031194      end 
  • trunk/actionpack/test/controller/routing_test.rb

    r6231 r6343  
    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 
  • trunk/actionpack/test/controller/url_rewriter_test.rb

    r6314 r6343  
    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 
     
    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][]' => '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 
    164205end 
  • trunk/activesupport/lib/active_support/core_ext/hash/conversions.rb

    r6148 r6343  
    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 
     
    1616class Array 
    1717  def to_query(key) #:nodoc: 
    18     collect { |value| value.to_query("#{key}[]") } * '&' 
     18    collect { |value| value.to_query("#{key}[]") }.sort * '&' 
    1919  end 
    2020end 
     
    4949          collect do |key, value| 
    5050            value.to_query(namespace ? "#{namespace}[#{key}]" : key) 
    51           end * '&' 
     51          end.sort * '&' 
    5252        end 
    5353