Links to user-specified urls interpreted as relative urls
-
18-04-2021 - |
Question
Sorry if this question has been answered elsewhere, but I've spent awhile looking with no luck.
In my web app, I ask users to specify urls to their blogs. However, they don't always put "http://" at the beginning of these urls. Elsewhere on the site, when I link to these urls, the browser interprets them as relative urls. e.g. if the user writes bobsblog.wordpress.com, the link goes to http://www.mydomain.com/bobsblog.wordpress.com.
One solution is to pre-populate the url field with "http://".
But a nicer solution would be to parse the url and add the scheme if the user hasn't. Does rails offer a good way to do this? I looked at the function URI::parse, but it doesn't seem to offer a good way of doing that.
Solution
You could use URI.parse and check the scheme.
before_save :sanitize_url
def sanitize_url
uri = URI.parse(url)
self.url = "http://#{url}" if uri.scheme.blank?
rescue URI::InvalidURIError => e
# not a parseable URI, so you need to handle that
end
Here some output
ree-1.8.7-2011.03 :035 > x = URI.parse "http://google.com"
=> #<URI::HTTP:0x1069720c8 URL:http://google.com>
ree-1.8.7-2011.03 :036 > x.scheme
=> "http"
ree-1.8.7-2011.03 :037 > y = URI.parse "google.com"
=> #<URI::Generic:0x1069672e0 URL:google.com>
ree-1.8.7-2011.03 :038 > y.scheme
=> nil
ree-1.8.7-2011.03 :039 > z = URI.parse "https://google.com"
=> #<URI::HTTPS:0x10695b8f0 URL:https://google.com>
ree-1.8.7-2011.03 :040 > z.scheme
=> "https"
OTHER TIPS
Maybe in your model, you could have a method to return the URL as an absolute URL. If it doesn't start with "http://", just add it to the front.
def abs_url
(url.start_with? "http://") ? url : ("http://" + url)
end
And in your view, just do something like @user.abs_url
.
Edit: Oh, I didn't realize, but you probably wanted to do this upon submission. Similar logic can be done before the save. In that case:
before_save :abs_url
...
def abs_url
url = (url.start_with? "http://") ? url : ("http://" + url)
end
And the URL will be saved with the "http://" in the front.