开发者

Is there a Ruby library/gem that will generate a URL based on a set of parameters?

Rails' URL generation mechanism (most of which routes through polymorphic_url at some point) allows for the passing of a hash 开发者_运维百科that gets serialized into a query string at least for GET requests. What's the best way to get that sort of functionality, but on top of any base path?

For instance, I'd like to have something like the following:

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

I could certainly write my own that strictly suits my application's requirements, but if there existed some canonical library to take care of it, I'd rather use that :).


Yes, in Ruby's standard library you'll find a whole module of classes for working with URI's. There's one for HTTP. You can call #build with some arguments, much like you showed.

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

For the query string itself, just use Rails' Hash addition #to_query. i.e.

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


Late to the party, but let me highly recommend the Addressable gem. In addition to its other useful features, it supports writing and parsing uri's via RFC 6570 URI templates. To adapt the given example, try:

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

or

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


With vanilla Ruby, use 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"


I would suggest my iri gem, which makes it easy to build a URL through a fluent interface:

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜