join(*str) public

Synopsis

URI::join(str[, str, ...])

Args

str

String(s) to work with, will be converted to RFC3986 URIs before merging.

Description

Joins URIs.

Usage

require 'uri'

p URI.join("http://example.com/","main.rbx")
# => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>

p URI.join('http://example.com', 'foo')
# => #<URI::HTTP:0x01ab80a0 URL:http://example.com/foo>

p URI.join('http://example.com', '/foo', '/bar')
# => #<URI::HTTP:0x01aaf0b0 URL:http://example.com/bar>

p URI.join('http://example.com', '/foo', 'bar')
# => #<URI::HTTP:0x801a92af0 URL:http://example.com/bar>

p URI.join('http://example.com', '/foo/', 'bar')
# => #<URI::HTTP:0x80135a3a0 URL:http://example.com/foo/bar>
Show source
Register or log in to add new notes.
April 16, 2010
1 thank

Also behaves like File#expand_path

You can also use URI.join to resolve relative and absolute links:

URI.join('http://example.com/', '/example').to_s
# => "http://example.com/example"

URI.join('http://example.com/example', 'test').to_s
# => "http://example.com/test"

URI.join('http://example.com/example/', 'test').to_s
# => "http://example.com/example/test"

URI.join('http://example.com/example/foo', '../css').to_s
# => "http://example.com/css"
February 23, 2012
0 thanks

Be careful with path vs. endpoint

URI.join uses a delimiter – forward slash (/) – to decide if joined strings are a path or endpoint. In order to include strings as part of the path, they must end with a forward slash (/). Otherwise, they are assumed to be an endpoint and are overritten by your new “endpoint”.

Used this way, it (kind of) makes sense:

1.9.2p290 :021 > URI.join("http://localhost/test","main.json")
 => #<URI::HTTP:0x007fa68e81c270 URL:http://localhost/main.json> 

1.9.2p290 :022 > URI.join("http://localhost/test/","main.json")
 => #<URI::HTTP:0x007fa68e80e0d0 URL:http://localhost/test/main.json> 

It is especially confusing when you pass 3 strings and the 3rd (your endpoint) overwrites the 2nd (which you expected to be part of the path).

1.9.2p290 :023 > URI.join("http://localhost/", "test", "main.json")
 => #<URI::HTTP:0x007fa68cec0ba0 URL:http://localhost/main.json> 

1.9.2p290 :024 > URI.join("http://localhost/", "test/", "main.json")
 => #<URI::HTTP:0x007fa68ce14c60 URL:http://localhost/test/main.json> 

Now, consider that you are probably using a variable for the string value of ‘test’.

1.9.2p290 :025 > controller = 'test'
1.9.2p290 :026 > URI.join("http://localhost/", controller, "main.json")
 => #<URI::HTTP:0x007fa68cec0ba0 URL:http://localhost/main.json> 

Your `controller` is simply ignored. Or rather, your endpoint(?) was overwritten.

I’m not sure what versions of ruby this affects. As you can see I am using 1.9.2p290.