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

时间:2021-09-22 21:32:19

In Python, I can do this:

在Python中,我可以这样做:

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

In Ruby[+Rails] I can't figure out how to do the same thing without "rolling my own," which seems odd. The Rails way doesn't work for me -- it adds square brackets to the names of the query parameters, which the server on the other end may or may not support:

在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"

My use case is simply that I wish to muck with the values of some of the values in the query-string portion of the URL. It seemed natural to lean on the standard library and/or Rails, and write something like this:

我的用例很简单,我希望使用URL的查询字符串部分中的某些值的值。依靠标准库和/或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)

but only if the resulting URI is in fact http://example.com/foo?a=b&a=c&a=d, and not http://example.com/foo?a[]=b&a[]=c&a[]=d. Is there a correct or better way to do this?

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

5 个解决方案

#1


24  

In modern ruby this is simply:

在现代红宝石中,这很简单:

require 'uri'
URI.encode_www_form(hash)

#2


5  

Here's a quick function to turn your hash into query parameters:

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

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

#3


1  

Quick Hash to a URL Query Trick :

快速哈希到URL查询技巧:

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

# => "http://www.example.com?language=ruby&status=awesome"

Want to do it in reverse? Use CGI.parse:

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

require 'cgi' 
# Only needed for IRB, Rails already has this loaded

CGI::parse "language=ruby&status=awesome"

# => {"language"=>["ruby"], "status"=>["awesome"]} 

#4


0  

The way rails handles query strings of that type means you have to roll your own solution, as you have. It is somewhat unfortunate if you're dealing with non-rails apps, but makes sense if you're passing information to and from rails apps.

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

#5


-1  

As a simple plain Ruby solution (or RubyMotion, in my case), just use this:

作为一个简单的纯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"

It only handles simple hashes, though.

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

#1


24  

In modern ruby this is simply:

在现代红宝石中,这很简单:

require 'uri'
URI.encode_www_form(hash)

#2


5  

Here's a quick function to turn your hash into query parameters:

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

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

#3


1  

Quick Hash to a URL Query Trick :

快速哈希到URL查询技巧:

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

# => "http://www.example.com?language=ruby&status=awesome"

Want to do it in reverse? Use CGI.parse:

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

require 'cgi' 
# Only needed for IRB, Rails already has this loaded

CGI::parse "language=ruby&status=awesome"

# => {"language"=>["ruby"], "status"=>["awesome"]} 

#4


0  

The way rails handles query strings of that type means you have to roll your own solution, as you have. It is somewhat unfortunate if you're dealing with non-rails apps, but makes sense if you're passing information to and from rails apps.

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

#5


-1  

As a simple plain Ruby solution (or RubyMotion, in my case), just use this:

作为一个简单的纯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"

It only handles simple hashes, though.

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