Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert ruby hash to URL query string ... without those square brackets

In Python, I can do this:

>>> 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:

>> 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:

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?

like image 995
Charlie Avatar asked Jan 11 '11 06:01

Charlie


3 Answers

In modern ruby this is simply:

require 'uri'
URI.encode_www_form(hash)
like image 116
Aaron Jensen Avatar answered Sep 28 '22 18:09

Aaron Jensen


Quick Hash to a URL Query Trick :

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

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

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

# => {"language"=>["ruby"], "status"=>["awesome"]} 
like image 27
FaaduBaalak Avatar answered Sep 28 '22 18:09

FaaduBaalak


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
like image 24
Miles Zimmerman Avatar answered Sep 28 '22 18:09

Miles Zimmerman