Add parameter to url

Since you may have multiple query parameters you want to add and not just one, here's a version that lets you append as many params as you want by simply passing in a hash ... Plus a Hash seems like a more natural way to pass in params anyway, even if you're only adding one param.

  require 'uri'
  def add_params(url, params = {})
    uri = URI(url)
    params    = Hash[URI.decode_www_form(uri.query || '')].merge(params)
    uri.query =      URI.encode_www_form(params)
    uri.to_s
  end

Examples:

pry(main)> helper.add_params("http://example.com", b: 2)
=> "http://example.com?b=2"

pry(main)> helper.add_params("http://example.com?a=1", b: 2, c: 3)
=> "http://example.com?a=1&b=2&c=3"

pry(main)> helper.add_params("http://www.youtube.com/watch?v=og9B3BEnBHo", wmode: 'opaque')
=> "http://www.youtube.com/watch?v=og9B3BEnBHo&wmode=opaque"

As Ruby has evolved over the years the answer differs between versions.

After 1.9.2

Ruby 1.9.2 saw decode_www_form and encode_www_form added to the URI module, making encoding parameters easier.

require 'uri'

uri = URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
new_query_ar = URI.decode_www_form(uri.query || '') << ["wmode", "opaque"]
uri.query = URI.encode_www_form(new_query_ar)
puts uri.to_s

Explanation

URI.decode_www_form breaks a string of query parameters (uri.query) into a nested array of parameters ([["v", "og9B3BEnBHo"]])

uri.query || '' supplies either the query string of the uri, or if it does not exist, an empty string. This prevents decode_www_form from running into an error if uri.query is nil.

<< ["wmode", "opaque"] adds another element to the array of query parameters. You may add more by further extending new_query_ar: new_query_ar << ["fullscreen", "1"]

URI.encode_www_form encodes the nested array new query parameters into a string.

Before 1.9.2

require 'uri'

uri = URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
uri.query = [uri.query, "wmode=opaque"].compact.join('&') 
puts uri.to_s

Explanation

[uri.query, "wmode=opaque"] is an array of all the eventual query parameters. You may add more by extending the array: [uri.query, "wmode=opaque", "fullscreen=1"] or by adding to the final element: "wmode=opaque&fullscreen=1"

compact removes nil elements from an array, thus it removes uri.query if there is not an existing query parameter.

join, finally, joins them into a query string.


require 'uri'

uri =  URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
uri.query = [uri.query, "wmode=opaque"].compact.join('&') 
puts uri.to_s

#edit Since 1.9.2 there are methods added to the URI module

uri =  URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
new_query_ar = URI.decode_www_form(String(uri.query)) << ["wmode", "opaque"]
uri.query = URI.encode_www_form(new_query_ar)
puts uri.to_s

(The call to String ensures that this also works in the case when the original URI does not have a query string)