Convert ruby โ€‹โ€‹hash to URL query string ... without these 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 cannot figure out how to do the same without โ€œrolling my own,โ€ which seems strange. The Rails method does not work for me - it adds square brackets to the names of the request parameters that the server at 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 just that I want to extinguish the values โ€‹โ€‹of some values โ€‹โ€‹in the query-string part of the URL. It was natural to rely 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 actually 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 right or best way to do this?

+6
uri ruby-on-rails hash params
source share
5 answers

In a modern ruby, it's simple:

 require 'uri' URI.encode_www_form(hash) 
+17
source share

Here is 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 
+6
source share

Fast hashed URL request:

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

Want to do it the other way around? Use CGI.parse:

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

The way rails handle query strings of this type means that you must roll your own solution, just like yours. It is somewhat sad if you are dealing with applications other than rails, but it makes sense if you transfer information to and from rails applications.

0
source share

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

 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 processes only simple hashes.

-one
source share

All Articles