I'd like to create an URL using an endpoint and a path or a host and path. Unfortunately URI.join
doesn't allow to do it:
pry(main)> URI.join "https://service.com", "endpoint", "/path"
=> #<URI::HTTPS:0xa947f14 URL:https://service.com/path>
pry(main)> URI.join "https://service.com/endpoint", "/path"
=> #<URI::HTTPS:0xabba56c URL:https://service.com/path>
and what I want is: "https://service.com/endpoint/path"
. How could I do it in Ruby/Rails?
EDIT: As the URI.join
has some drawback, I'm tempted to use File.join
:
URI.join("https://service.com", File.join("endpoint", "/path"))
What do you think?
URI.join works like what you'd expect an <a>
tag to work.
You're joining example.com
, endpoint
, /path
, so /path
takes you back to the root of the domain, instead of appending it.
You need to end the endpoint with a /
, and not start the path with /
.
URI.join "https://service.com/", "endpoint/", "path"
=> #<URI::HTTPS:0x007f8a5b0736d0 URL:https://service.com/endpoint/path>
Edit: As per your request in the comment below, try this:
def join(*args)
args.map { |arg| arg.gsub(%r{^/*(.*?)/*$}, '\1') }.join("/")
end
Test:
> join "https://service.com/", "endpoint", "path"
=> "https://service.com/endpoint/path"
> join "http://example.com//////", "///////a/////////", "b", "c"
=> "http://example.com/a/b/c"
Looks like URI.join checks for the presence of slash character '/' to figures out the folder in the url path. So, if you missed the trailing slash '/' in the path it will not treat it as folder, and omit it. Check this out:
URI.join("https://service.com", 'omitted_part', 'omitted_again', 'end_point_stays').to_s
# =>"https://service.com/end_point_stays"
Here, if we try to JOIN THE WORDS ONLY, first and last params only stay, rest are omitted, where first param is, absolute uri with protocol & last param is, the end point.
So, if you want to include the folder component, add trailing slash in each folder-component, then only it is considered part of the path:
URI.join("https://service.com", 'omitted_no_trailing_slash', 'omitted_again', 'stays/', 'end_point_stays').to_s
# => "https://service.com/stays/end_point_stays"
One more interesting thing to consider is that, if you are providing path in first parameter it acts as follows:
URI.join("https://service.com/omitted_because_no_trailing_slash", 'end_point_stays').to_s
# => "https://service.com/end_point_stays"
URI.join("https://service.com/stays_because_of_trailing_slash/", 'end_point_stays').to_s
# => "https://service.com/stays_because_of_trailing_slash/end_point_stays"
URI.join("https://service.com/safe_with_trailing_slash/omitted_because_no_trailing_slash", 'end_point_stays').to_s
# => "https://service.com/safe_with_trailing_slash/end_point_stays"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With