I’ve been working on a project using Rails v4 and ran into an interesting question about which there seems to be a lot of confusion. Rails has convenient helper functions for generating REST-style links:
*_url. It seems everyone is clear on the fact that the
_path version gives a relative path, whereas the
_url version gives an absolute URL. The confusion lies in when is it appropriate to use which one? The general guidance is to use paths in views and urls in controllers … but there isn’t really an explanation for why. I found a StackOverflow question and answer that seems to answer the question, but it didn’t sound like a very confident answer and seemed to be based a bit on hearsay. So I decided to dig in and look at the various specifications and documentation and see if I couldn’t figure it out for myself …
From this article I found the guidance that there are two situations where one needs to use the absolute URL:
- When redirecting to another page
- When switching to or from SSL (
httpor vice versa)
Other than those two cases, using the relative path is fine. I’m going to skip over the SSL one because there seems to be plenty of agreement on that one.
In my earlier investigation I had already looked into the HTTP protocol specification and found the relevant section on redirects and the definition of the Location field. The specification does explicitly say that an absolute URI should be used. Most people seem to be hand-waving this away saying that “modern browsers understand” if you use a relative path, which is fine for them I guess. I don’t like making a potential bug for myself later on by using undocumented features if I don’t have to. So I kept looking to see if I couldn’t find a definitive answer.
That’s when I looked specifically at the documentation for the Rails
redirect_to method. It states that the first parameter can take one of a few forms. There are actually two entries in that list regarding
http://) or a protocol relative reference (like
//) is passed straight through as the target for redirection
Stringnot containing a protocol - The current protocol and host is prepended to the string
And there is our answer. The Rails
redirect_to method automatically converts our relative paths into absolute urls for the Location field in the redirect response.1 So we only need to use an absolute URL when changing protocols or when an absolute URL is truly needed (like a link in an email or something).
As long as in your configuration the URL is just the path with the protocol and host prepended, but this is the default configuration so it will be the common case. ↩