Here’s a change in behavior I would love on the mailers.
Backstory
When you send an email, you’ll likely need links. Those links must be the full path i.e. ‘http://example.com/foo’ instead of relative (just ‘/foo’). Unfortunately most devs are so used to using the *_path helpers, they use them in emails by mistake.
I made this mistake recently with http://www.codetriage.com, here’s the PR that fixes it (https://github.com/codetriage/codetriage/pull/257). The sad part is I didn’t realize there was a problem until a user got an email and couldn’t click on a link. Then they had to be nice enough to report it. If your business is running on Rails, this may take days. I’ve been doing this for years, and it still happens to me.
Feature
Here’s what I would like to see happen. Either raise an exception when *_path helpers are used in a mail template so my tests would have caught it, or likely just have *_path helpers resolve to the full URL by default. What do you think?
As a solution i would prefer to resolve the full URL by default. Raising an exception seems to me a bit like rails telling the programmer „I know what you’re intending, and we both know the solution but you have to fix it on your own."
As a solution i would prefer to resolve the full URL by default. Raising
an exception seems to me a bit like rails telling the programmer „I know
what you’re intending, and we both know the solution but you have to fix it
on your own."
Breaking the strong expectation that *_path generates a path is dubious to
me. Too clever, the API is kind of cheating in my mind.
I've been thinking about it and my only conclusion by now is that we agree
there's something to do here, but see cons in all proposals so far :).
Are there any valid uses for *_path in an email? Can you do reference links with ID elements in an email? We could make it configurable. Default it to non-hair-pulling behavior, but allow anyone with a legitimate *_path use to preserve functionality.
config.action_mailer.path_helper_behavior = :raise
config.action_mailer.path_helper_behavior = :url
config.action_mailer.path_helper_behavior = :make_me_lose_users_or_money # i.e. current behavior
Nope it wouldn’t. Rendering the emails don’t currently raise errors, so your tests will still pass. The only way to find out is to actually get the email and click on it. Even if you look at it in mail_view you get the right URL generated as the relative path will work.
I cannot think of a valid use case for *_path in mailer views, so after
thinking about it I personally would be inclined to remove them.
People cannot upgrade and have their mailers crashing in production, so I
think we have no option but to go through a deprecation cycle.
If someone had a rare need to generate a path and the helpers were gone,
they could still opt-in via *_url(only_path: true), which is something we
could document in small font :).
The mailer guide would need to reflect these changes.
For HTML emails, using a <base> tag allows you to use relative URLs safely.
It's easier to specify the base path in a single place and and use
relative URLs, as opposed to using an absolute path with the same base path
in every link (which is not very DRY).
Unfortunately, such an approach does not work for plain text email, so it
makes sense to deprecate them in the plain text case (if it is possible to
do so only in that case, but allow it for HTML email).
Unfortunately, for mail_view, I don't think the <base> tag approach will
work, unless you used a new window/frame for the HTML email.
I have never checked it myself (could be cargo culting), but my
understanding has always been that using the BASE tag is not a good
practice for portable HTML emails. See for example:
I personally believe preventing *_path calls that are plain wrong and a
common gotcha outweights supporting this edge-case that can still be
accomplished with only_path: true.