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)