12

I'd like to do some sanitization of query params.

I parse the query with CGI.parse, then I delete some params, but I can't find an opposite method to build the query.

I don't really want to do something like

params.map{|n,v| "#{CGI.escape n}=#{CGI.escape v.to_s}"}.join("&")

There's got to be a simpler way. Is there?

Leonid Shevtsov
  • 14,024
  • 9
  • 51
  • 82

4 Answers4

9

There is a nice method in URI module:

require 'uri'
URI.encode_www_form("q" => "ruby", "lang" => "en")  #=> "q=ruby&lang=en"
ujifgc
  • 2,215
  • 2
  • 19
  • 21
3

If you're using Rails (or don't mind pulling in ActiveSupport), then you can use to_param (AKA to_query):

{ :a => '&', :b => 'Where is pancake house?', :c => ['an', 'array'] }.to_param
# a=%26&b=Where+is+pancake+house%3F&c%5B%5D=an&c%5B%5D=array

to_param handles arrays a little differently than your version though, it'll put out c[]=an&c[]=array rather than just c=an&c=array.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
2

While there's no better answer, I'll put up the method which I'm using now.

def build_query(params)
  params.map do |name,values|
    values.map do |value|
      "#{CGI.escape name}=#{CGI.escape value}"
    end
  end.flatten.join("&")
end
Leonid Shevtsov
  • 14,024
  • 9
  • 51
  • 82
0

I am not sure if the following is a simplification, but it avoids expanding the (key, value) pairs of a hash.

params.map{|qq| qq.map{|q| CGI.escape(q)}.join('=')}.join('&')
sawa
  • 165,429
  • 45
  • 277
  • 381