5
\$\begingroup\$
if(env['REQUEST_METHOD'] == 'POST')
 $post = {}
 post = env['rack.input'].read.split('&')
 post_split = Array.new
 post.each{|x| post_split << x.split('=')}
 post_split.each{|x|
 $post[x[0]] = x[1]
 }
end

What would be a nice way to do this? I have a string like:

"a=b&c=d"

and i'm trying to get it into a hash like

{:a=>'b',:c=>'d'}

This code works but it is just terrible, and I can't access the keys with

$post[:a] 

only

$post['a']
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 21, 2011 at 15:00
\$\endgroup\$

3 Answers 3

5
\$\begingroup\$

The Rack gem has a built-in function to parse the query. If your project depends on rack (e.g. it's a Rails app), then you can use it.

Rack::Utils.parse("a=b&c=d")
# { :a => 'b', :c => 'd' }

If your project doesn't depend on rack, you can copy the method in your code.

DEFAULT_SEP = /[&;] */n
# Stolen from Mongrel, with some small modifications:
# Parses a query string by breaking it up at the '&'
# and ';' characters. You can also use this to parse
# cookies by changing the characters used in the second
# parameter (which defaults to '&;').
def parse_query(qs, d = nil)
 params = {}
 (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
 k, v = p.split('=', 2).map { |x| unescape(x) }
 if cur = params[k]
 if cur.class == Array
 params[k] << v
 else
 params[k] = [cur, v]
 end
 else
 params[k] = v
 end
 end
 return params
end
answered Aug 28, 2011 at 20:24
\$\endgroup\$
1
  • \$\begingroup\$ Seems in the newer versions parse is remove and now one need to call parse_query instead. \$\endgroup\$ Commented Jul 24, 2014 at 8:03
5
\$\begingroup\$

better way of such parsing is not to reinvent the wheel and use existing ruby functionality

require "cgi"
post = CGI.parse "a=b&c=d"
# => {"a"=>["b"], "c"=>["d"]}

hash values are arrays here, but it makes sense, as you can have several vars in your query string with the same name

for the second part of your question (accessing the keys as symbols) you can use .with_indifferent_access method provided by ActiveSupport (it is already loaded if you use rails)

post.with_indifferent_access[:a]
# => ["b"]
answered Aug 25, 2011 at 16:39
\$\endgroup\$
4
\$\begingroup\$

If you can do without symbol keys, the following builds a Hash without any external dependencies:

s = "a=b&c=d"

Hash[*s.split(/=|&/)] => {"a"=>"b", "c"=>"d"}

answered Sep 4, 2011 at 2:56
\$\endgroup\$
1
  • \$\begingroup\$ Will fail for "a=b&c=". \$\endgroup\$ Commented Jul 24, 2014 at 8:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.