I am looking for a function that converts a hash into a query string. I know Rack::Utils.build_query
but it use +
for spaces.
Asked
Active
Viewed 599 times
-1

powerboy
- 10,523
- 20
- 63
- 93
-
Why does it matter if you use `+` or `%20`? They should be interpreted as the same thing when decoding. – mu is too short Oct 27 '13 at 22:39
-
Think of an api endpoint that requires you to compute a signature based on the query string. – powerboy Oct 27 '13 at 22:50
-
In that case, wouldn't you need to parse the URL, standardize it (so that `?a=b&c=d` and `?c=d&a=b` really do come out the same), and then put it back together? Then your "put it back together" step would standardize on `+` or `%20` for spaces. – mu is too short Oct 28 '13 at 00:27
2 Answers
0
build_query
makes use of Rack::Utils.escape
, which replaces spaces with + characters. You could add a version of build_query that makes use of Rack::Utils.escape_path
, e.g.
module Rack::Utils
def your_build_query(params)
params.map { |k, v|
if v.class == Array
build_query(v.map { |x| [k, x] })
else
v.nil? ? escape_path(k) : "#{escape_path(k)}=#{escape_path(v)}"
end
}.join("&")
end
end
But all escape_path(s)
does is escape(s).gsub('+', '%20')
, so you could just call Rack::Utils.build_query(s).gsub('+', '%20')
.

struthersneil
- 2,700
- 10
- 11
-
It surely works but essentially it does `str.gsub(' ', '+').gsub('+', '%20')` which it is not ideal. – powerboy Oct 27 '13 at 22:51
0
Have you looked at URI::encode_www_form
? It's built into Ruby.
From the documentation:
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"
As for the question of using %20
or +
, see "When to encode space to plus (+) or %20?".

Community
- 1
- 1

the Tin Man
- 158,662
- 42
- 215
- 303
-
`URI.encode_www_form` is not different from `Rack::Utils.build_query`. "This method doesn’t convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP (ASCII space) to + and converts others to %XX." – powerboy Oct 28 '13 at 01:20