有没有一个基于一组参数生成URL的Ruby库/宝石?

32

Rails的URL生成机制(大部分通过polymorphic_url路由)允许传递一个哈希值,在GET请求中至少被序列化为查询字符串。如何在任何基本路径上获取这种功能的最佳方法?

例如,我想要像下面这样的东西:

generate_url('http://www.google.com/', :q => 'hello world')
  # => 'http://www.google.com/?q=hello+world'

我当然可以编写适合我的应用程序要求的代码,但如果存在一些标准库来处理这个问题,我宁愿使用它 :)

4个回答

47

是的,在Ruby的标准库中,你会找到一个用于处理URI的模块。其中有一个用于HTTP。你可以像你展示的那样,使用一些参数调用#build

http://www.ruby-doc.org/stdlib/libdoc/uri/rdoc/classes/URI/HTTP.html#M009497

对于查询字符串本身,只需使用Rails的哈希加法#to_query。即:

uri = URI::HTTP.build(:host => "www.google.com", :query => { :q => "test" }.to_query)

1
太棒了!我从未见过URI模块,所以这非常酷。 - Steven
2
undefined method 'to_query' for #<Hash:0x1c943d0> (NoMethodError) - Nakilon
4
如果你不使用Rails,这个方法就不可用了。有没有其他的替代方法? - Stefan Hendriks
3
这不是真的:URI模块是一个标准的ruby库 - 它不需要Rails。在使用本答案中的代码之前,你必须输入require 'uri'。否则它将按照广告所述的工作。 - Steve Midgley
5
Hash#to_query的替代方法是URI.encode_www_form - tokland
显示剩余8条评论

7
迟到了,但是让我强烈推荐Addressable宝石。除了其他有用的功能外,它还支持通过RFC 6570 URI模板编写和解析uri。要适应给定的示例,请尝试:
gsearch = Addressable::Template.new('http://google.com/{?query*}')
gsearch.expand(query: {:q => 'hello world'}).to_s
# => "http://www.google.com/?q=hello%20world"

或者

gsearch = Addressable::Template.new('http://www.google.com/{?q}')
gsearch.expand(:q => 'hello world').to_s
# => "http://www.google.com/?q=hello%20world"

请查看此URL,它对提升您的内容质量有帮助。 - Willie Cheng
整理了一下并添加了示例。感谢@willie! - wobh
我注意到Thor gem只在Ruby 1.8中使用Addressable。之后是否添加了其他内容,以便不再需要它? - labyrinth

3
使用原始的 Ruby,可以使用 URI.encode_www_form 函数来进行编码,具体用法请参考这里
require 'uri'
query = URI.encode_www_form({ :q => "test" })
url = URI::HTTP.build(:host => "www.google.com", query: query).to_s
#=> "http://www.google.com?q=test"

1

我建议使用我的iri宝石,它通过流畅的界面轻松构建URL:

require 'iri'
url = Iri.new('http://google.com/')
  .append('find').append('me') # -> http://google.com/find/me
  .add(q: 'books about OOP', limit: 50) # -> ?q=books+about+OOP&limit=50
  .del(:q) # remove this query parameter
  .del('limit') # remove this one too
  .over(q: 'books about tennis', limit: 10) # replace these params
  .scheme('https') # replace 'http' with 'https'
  .host('localhost') # replace the host name
  .port('443') # replace the port
  .path('/new/path') # replace the path of the URI, leaving the query untouched
  .cut('/q') # replace everything after the host and port
  .to_s # convert it to a string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接