Monday, November 2, 2009

Convert an encoded URL query string into a nested hash in a Rails App

On my work with churchservicefinder.com, I wanted to parse out the following string, and produce a nested hash of the query part, just like rails does.

I search the web and found no answer. So I searched through the rails source code and found the answer in the Rack gem.

The command is Rack::Utils.parse_nested_query

Here is my example:

Loading development environment (Rails 2.3.4)
>> ab = "http://localhost:3000/churches/list/address/27713/5?fr[ed]=0&fr[ed]=1&fr[d]=0&fr[tz]=1&fr[et]=0&fr[et]=1&fr[tw]=0&fr[t_opr]=before&fr[t_opt(4i)]=9&fr[t_opt(5i)]=00&commit=Filter+Results"
=> "http://localhost:3000/churches/list/address/27713/5?fr[ed]=0&fr[ed]=1&fr[d]=0&fr[tz]=1&fr[et]=0&fr[et]=1&fr[tw]=0&fr[t_opr]=before&fr[t_opt(4i)]=9&fr[t_opt(5i)]=00&commit=Filter+Results"
>> c = URI.parse(ab)
=> #
>>
?> d = Rack::Utils.parse_nested_query(c.query)
=> {"commit"=>"Filter Results", "fr"=>{"t_opt(4i)"=>"9", "t_opt(5i)"=>"00", "tw"=>"0", "et"=>"1", "d"=>"0", "tz"=>"1", "t_opr"=>"before", "ed"=>"1"}}
>> d = Rack::Utils.parse_nested_query(c.query).symbolize_keys
=> {:commit=>"Filter Results", :fr=>{"t_opt(4i)"=>"9", "t_opt(5i)"=>"00", "tw"=>"0", "et"=>"1", "d"=>"0", "tz"=>"1", "t_opr"=>"before", "ed"=>"1"}}
>> e = d[:fr].symbolize_keys
=> {:tz=>"1", :d=>"0", :"t_opt(4i)"=>"9", :ed=>"1", :et=>"1", :"t_opt(5i)"=>"00", :tw=>"0", :t_opr=>"before"}