Ruby,如何将一个param添加到一个你不知道它是否已经有任何其他param的URL

fgu*_*len 14 ruby url params

我必须在不确定的URL中添加一个新的参数param=value.

如果实际的URL已经像这样params

http://url.com?p1=v1&p2=v2
Run Code Online (Sandbox Code Playgroud)

我应该将URL转换为另一个:

http://url.com?p1=v1&p2=v2&param=value
Run Code Online (Sandbox Code Playgroud)

但是如果URL没有任何参数,那么:

http://url.com
Run Code Online (Sandbox Code Playgroud)

我应该将URL转换为另一个:

http://url.com?param=value
Run Code Online (Sandbox Code Playgroud)

我觉得用Regex解决这个问题很担心,因为我不确定寻找存在&就足够了.我想也许我应该将URL转换为URI对象,然后添加param并再次将其转换为String.

寻找已经处于这种情况的人的任何建议.

更新

为了帮助参与,我正在共享一个基本的测试套件:

require "minitest"
require "minitest/autorun"

def add_param(url, param_name, param_value)
  # the code here
  "not implemented"
end

class AddParamTest < Minitest::Test
  def test_add_param
    assert_equal("http://url.com?param=value", add_param("http://url.com", "param", "value"))
    assert_equal("http://url.com?p1=v1&p2=v2&param=value", add_param("http://url.com?p1=v1&p2=v2", "param", "value"))
    assert_equal("http://url.com?param=value#&tro&lo&lo", add_param("http://url.com#&tro&lo&lo", "param", "value"))
    assert_equal("http://url.com?p1=v1&p2=v2&param=value#&tro&lo&lo", add_param("http://url.com?p1=v1&p2=v2#&tro&lo&lo", "param", "value"))
  end
end
Run Code Online (Sandbox Code Playgroud)

Aru*_*hit 26

require 'uri'

uri = URI("http://url.com?p1=v1&p2=2")
ar = URI.decode_www_form(uri.query) << ["param","value"]
uri.query = URI.encode_www_form(ar)
p uri #=> #<URI::HTTP:0xa0c44c8 URL:http://url.com?p1=v1&p2=2&param=value>

uri = URI("http://url.com")
uri.query = "param=value" if uri.query.nil?
p uri #=> #<URI::HTTP:0xa0eaee8 URL:http://url.com?param=value>
Run Code Online (Sandbox Code Playgroud)

编辑:(通过fguillen,合并所有好的命题,并使其与他的问题测试套件兼容.)

require 'uri'

def add_param(url, param_name, param_value)
  uri = URI(url)
  params = URI.decode_www_form(uri.query || "") << [param_name, param_value]
  uri.query = URI.encode_www_form(params)
  uri.to_s
end
Run Code Online (Sandbox Code Playgroud)

  • 不需要条件:`URI.decode_www_form(uri.query ||"")`. (6认同)