143
votes

I have some URLs, like

http://www.example.com/something?param1=value1&param2=value2&param3=value3

and I would like to extract the parameters from these URLs and get them in a Hash. Obviously, I could use regular expressions, but I was just wondering if there was easier ways to do that with Ruby or Rails. I haven't found anything in the Ruby module URI but perhaps I missed something.

In fact, I need a method that would do that:

extract_parameters_from_url("http://www.example.com/something?param1=value1&param2=value2&param3=value3")
#=> {:param1 => 'value1', :param2 => 'value2', :param3 => 'value3'}

Would you have some advices?

8
Hash[*string.split('&').collect{|i|i.split('=')}.flatten] This would work too, but it's probably the worst option for this case. But still you might find this snippet interesting. (Posting as comment since I don't consider this an answer :-))Vojto

8 Answers

171
votes

I think you want to turn any given URL string into a HASH?

You can try http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075

require 'cgi'

CGI::parse('param1=value1&param2=value2&param3=value3')

returns

{"param1"=>["value1"], "param2"=>["value2"], "param3"=>["value3"]}
162
votes

I found myself needing the same thing for a recent project. Building on Levi's solution, here's a cleaner and faster method:

Rack::Utils.parse_nested_query 'param1=value1&param2=value2&param3=value3'
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}
106
votes

Just Improved with Levi answer above -

Rack::Utils.parse_query URI("http://example.com?par=hello&par2=bye").query

For a string like above url, it will return

{ "par" => "hello", "par2" => "bye" } 
48
votes

For a pure Ruby solution combine URI.parse with CGI.parse (this can be used even if Rails/Rack etc. are not required):

CGI.parse(URI.parse(url).query) 
# =>  {"name1" => ["value1"], "name2" => ["value1", "value2", ...] }
40
votes

There more than one ways, to solve your problem. Others has shown you the some tricks. I know another trick. Here is my try :-

require 'uri'
url = "http://www.example.com/something?param1=value1&param2=value2&param3=value3"
uri = URI(url)
# => #<URI::HTTP:0x89e4898 URL:http://www.example.com/something?param1=value1&param2=value2&param3=value3>
URI::decode_www_form(uri.query).to_h # if you are in 2.1 or later version of Ruby
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}
Hash[URI::decode_www_form(uri.query)] # if you are below 2.1 version of Ruby
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}

Read the method docomentation of ::decode_www_form.

14
votes

Check out the addressable gem - a popular replacement for Ruby's URI module that makes query parsing easy:

require "addressable/uri"
uri = Addressable::URI.parse("http://www.example.com/something?param1=value1&param2=value2&param3=value3")
uri.query_values['param1']
=> 'value1'

(It also apparently handles param encoding/decoding, unlike URI)

0
votes

you can also use this method


require 'uri'
require 'cgi'
uri = URI("https://example.com/?query=1&q=2&query=5")
a = CGI::parse(uri.query)
puts a                   #=> {"query"=>["1", "5"], "q"=>["2"]}
puts a["query"].to_s     #=> ["1", "5"]
puts a["query"][0]       #=>  1
puts a["query"][1]       #=>  5
puts a["q"][0]           #=>  2


its safe and much easier

-3
votes

In your Controller, you should be able to access a dictionary (hash) called params. So, if you know what the names of each query parameter is, then just do params[:param1] to access it... If you don't know what the names of the parameters are, you could traverse the dictionary and get the keys.

Some simple examples here.