这对于普通哈希来说很简单

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

这就意味着

"a=a&b=b"

但是你怎么处理更复杂的东西,比如

{:a => "a", :b => ["c", "d", "e"]} 

这应该转化为

"a=a&b[0]=c&b[1]=d&b[2]=e" 

或者更糟的是,(该怎么做)像这样的事情:

{:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]

非常感谢你的帮助!


当前回答

如果你在法拉第请求的上下文中,你也可以只是传递params哈希作为第二个参数,法拉第会照顾到正确的param URL部分:

faraday_instance.get(url, params_hsh)

其他回答

对于基本的、非嵌套的散列,Rails/ActiveSupport有object# to_query。

>> {:a => "a", :b => ["c", "d", "e"]}.to_query
=> "a=a&b%5B%5D=c&b%5B%5D=d&b%5B%5D=e"
>> CGI.unescape({:a => "a", :b => ["c", "d", "e"]}.to_query)
=> "a=a&b[]=c&b[]=d&b[]=e"

http://api.rubyonrails.org/classes/Object.html#method-i-to_query

class Hash
  def to_params
    params = ''
    stack = []

    each do |k, v|
      if v.is_a?(Hash)
        stack << [k,v]
      elsif v.is_a?(Array)
        stack << [k,Hash.from_array(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! 
    params
  end

  def self.from_array(array = [])
    h = Hash.new
    array.size.times do |t|
      h[t] = array[t]
    end
    h
  end

end

如果使用Ruby 1.9.2或更高版本,则可以使用URI。Encode_www_form如果你不需要数组。

例如(来自1.9.3的Ruby文档):

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"

您会注意到,数组值不是用包含[]的键名来设置的,就像我们在查询字符串中习惯的那样。encode_www_form使用的规范与HTML5对application/x-www-form-urlencoded data的定义一致。

{:a=>"a", :b=>"b", :c=>"c"}.map{ |x,v| "#{x}=#{v}" }.reduce{|x,v| "#{x}&#{v}" }

"a=a&b=b&c=c"

还有另一种方法。对于简单的查询。

最好的方法是使用Hash。To_params可以很好地处理数组。

{a: 1, b: [1,2,3]}.to_param
"a=1&b[]=1&b[]=2&b[]=3"