【问题标题】:Is there a Ruby library/gem that will generate a URL based on a set of parameters?是否有基于一组参数生成 URL 的 Ruby 库/gem?
【发布时间】:2011-05-27 12:27:38
【问题描述】:

Rails 的 URL 生成机制(其中大部分路由在某些时候通过 polymorphic_url)允许传递至少对于 GET 请求被序列化为查询字符串的哈希。获得这种功能的最佳方式是什么,但在任何基本路径之上?

例如,我想要如下内容:

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

我当然可以编写自己的代码来严格满足我的应用程序的要求,但如果存在一些规范的库来处理它,我宁愿使用它:)。

【问题讨论】:

    标签: ruby-on-rails ruby gem


    【解决方案1】:

    是的,在 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)
    

    【讨论】:

    • 太棒了!我不能说我以前见过 URI 模块,所以这太酷了。
    • undefined method 'to_query' for #<Hash:0x1c943d0> (NoMethodError)
    • 这仅在您使用 Rails 时有效。如果您不使用 Rails,还有其他选择吗?
    • @StefanHendriks 这不是真的:URI 模块是一个标准的 ruby​​ 库——它不需要 Rails。在使用此答案中的代码之前,您必须发出 require 'uri'。否则它会像宣传的那样工作。
    • 替代Hash#to_query: URI.encode_www_form
    【解决方案2】:

    聚会迟到了,但我强烈推荐Addressable gem。除了其他有用的功能外,它还支持通过RFC 6570 URI templates 编写和解析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!
    • 我注意到 Thor gem 只对 Ruby 1.8 使用 Addressable。之后是否添加了一些内容以使其不再需要?
    【解决方案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"
    

    【讨论】:

      【解决方案4】:

      我会推荐我的iri gem,它可以通过流畅的界面轻松构建 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
      

      【讨论】:

        猜你喜欢
        • 2011-12-21
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 2011-08-01
        • 2011-09-11
        • 2010-10-22
        • 2011-10-31
        • 2015-10-13
        相关资源
        最近更新 更多