Ruby: How to turn a hash into HTTP parameters?

后端 未结 14 1577
故里飘歌
故里飘歌 2020-12-07 06:46

That is pretty easy with a plain hash like

{:a => \"a\", :b => \"b\"} 

which would translate into

\"a=a&b=b\"
<         


        
相关标签:
14条回答
  • 2020-12-07 07:26
    {:a=>"a", :b=>"b", :c=>"c"}.map{ |x,v| "#{x}=#{v}" }.reduce{|x,v| "#{x}&#{v}" }
    
    "a=a&b=b&c=c"
    

    Here's another way. For simple queries.

    0 讨论(0)
  • 2020-12-07 07:27

    Steal from Merb:

    # File merb/core_ext/hash.rb, line 87
    def to_params
      params = ''
      stack = []
    
      each do |k, v|
        if v.is_a?(Hash)
          stack << [k,v]
        else
          params << "#{k}=#{v}&"
        end
      end
    
      stack.each do |parent, hash|
        hash.each do |k, v|
          if v.is_a?(Hash)
            stack << ["#{parent}[#{k}]", v]
          else
            params << "#{parent}[#{k}]=#{v}&"
          end
        end
      end
    
      params.chop! # trailing &
      params
    end
    

    See http://noobkit.com/show/ruby/gems/development/merb/hash/to_params.html

    0 讨论(0)
  • 2020-12-07 07:28
    require 'uri'
    
    class Hash
      def to_query_hash(key)
        reduce({}) do |h, (k, v)|
          new_key = key.nil? ? k : "#{key}[#{k}]"
          v = Hash[v.each_with_index.to_a.map(&:reverse)] if v.is_a?(Array)
          if v.is_a?(Hash)
            h.merge!(v.to_query_hash(new_key))
          else
            h[new_key] = v
          end
          h
        end
      end
    
      def to_query(key = nil)
        URI.encode_www_form(to_query_hash(key))
      end
    end
    
    2.4.2 :019 > {:a => "a", :b => "b"}.to_query_hash(nil)
     => {:a=>"a", :b=>"b"}
    
    2.4.2 :020 > {:a => "a", :b => "b"}.to_query
     => "a=a&b=b"
    
    2.4.2 :021 > {:a => "a", :b => ["c", "d", "e"]}.to_query_hash(nil)
     => {:a=>"a", "b[0]"=>"c", "b[1]"=>"d", "b[2]"=>"e"}
    
    2.4.2 :022 > {:a => "a", :b => ["c", "d", "e"]}.to_query
     => "a=a&b%5B0%5D=c&b%5B1%5D=d&b%5B2%5D=e"
    
    0 讨论(0)
  • 2020-12-07 07:33
    2.6.3 :001 > hash = {:a => "a", :b => ["c", "d", "e"]}
    => {:a=>"a", :b=>["c", "d", "e"]}
    2.6.3 :002 > hash.to_a.map { |x| "#{x[0]}=#{x[1].class == Array ? x[1].join(",") : x[1]}" 
    }.join("&")
    => "a=a&b=c,d,e"
    
    0 讨论(0)
  • 2020-12-07 07:34

    The best approach it is to use Hash.to_params which is the one working fine with arrays.

    {a: 1, b: [1,2,3]}.to_param
    "a=1&b[]=1&b[]=2&b[]=3"
    
    0 讨论(0)
  • 2020-12-07 07:44

    If you are using Ruby 1.9.2 or later, you can use URI.encode_www_form if you don't need arrays.

    E.g. (from the Ruby docs in 1.9.3):

    URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
    #=> "q=ruby&lang=en"
    URI.encode_www_form("q" => "ruby", "lang" => "en")
    #=> "q=ruby&lang=en"
    URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
    #=> "q=ruby&q=perl&lang=en"
    URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
    #=> "q=ruby&q=perl&lang=en"
    

    You'll notice that array values are not set with key names containing [] like we've all become used to in query strings. The spec that encode_www_form uses is in accordance with the HTML5 definition of application/x-www-form-urlencoded data.

    0 讨论(0)
提交回复
热议问题