将ruby hash转换为URL查询字符串…没有那些方括号

在Python中,我可以这样做:

>>> import urlparse, urllib >>> q = urlparse.parse_qsl("a=b&a=c&d=e") >>> urllib.urlencode(q) 'a=b&a=c&d=e' 

在Ruby [+ Rails]中,我无法弄清楚如何在没有“滚动我自己”的情况下做同样的事情,这看起来很奇怪。 Rails方式对我不起作用 – 它为查询参数的名称添加方括号,另一端的服务器可能支持也可能不支持:

 >> q = CGI.parse("a=b&a=c&d=e") => {"a"=>["b", "c"], "d"=>["e"]} >> q.to_params => "a[]=b&a[]=c&d[]=e" 

我的用例很简单,我希望使用URL的query-string部分中的某些值的值。 依靠标准库和/或Rails似乎很自然,写下这样的东西:

 uri = URI.parse("http://example.com/foo?a=b&a=c&d=e") q = CGI.parse(uri.query) q.delete("d") q["a"] << "d" uri.query = q.to_params # should be to_param or to_query instead? puts Net::HTTP.get_response(uri) 

但是,只有结果URI实际上是http://example.com/foo?a=b&a=c&a=d ,而不是http://example.com/foo?a[]=b&a[]=c&a[]=d 。 有没有正确或更好的方法来做到这一点?

在现代ruby中,这很简单:

 require 'uri' URI.encode_www_form(hash) 

这是一个将哈希变为查询参数的快速函数:

 require 'uri' def hash_to_query(hash) return URI.encode(hash.map{|k,v| "#{k}=#{v}"}.join("&")) end 

快速哈希到URL查询技巧

 "http://www.example.com?" + { language: "ruby", status: "awesome" }.to_query # => "http://www.example.com?language=ruby&status=awesome" 

想反向做吗? 使用CGI.parse:

 require 'cgi' # Only needed for IRB, Rails already has this loaded CGI::parse "language=ruby&status=awesome" # => {"language"=>["ruby"], "status"=>["awesome"]} 

rails处理该类型的查询字符串的方式意味着您必须像自己一样滚动自己的解决方案。 如果您正在处理非rails应用程序,这有点不幸,但如果您要在rails应用程序之间传递信息,那就有意义了。

作为一个简单的纯Ruby解决方案(或者在我的例子中是RubyMotion),只需使用:

 class Hash def to_param self.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join("&") end end { fruit: "Apple", vegetable: "Carrot" }.to_param # => "fruit=Apple&vegetable=Carrot" 

但它只处理简单的哈希值。