New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate *_path
methods in mailers
#15840
Deprecate *_path
methods in mailers
#15840
Conversation
Is there a good place for an integration test with a mailer? |
I think deprecating the behaviour would cause some pain. I had mentioned people reuse views in emails. Example: In one of my projects I used https://github.com/pokonski/public_activity, and render/reuse the same views from web/ update emails. The problem is, developer is forced to either use multiple views in this case, add a hack, or start using Any way to overcome this? |
@sgrif not sure about the best place. I added one here: https://github.com/rails/rails/pull/15840/files#diff-6cd2f2bc2d75ddac6c0d1e85983e983dR406 in mailer_previews_test @vipulnsward are you on the rails-contributors mailing list? We've talked about this behavior a bit. Sharing views between emails and mailers should be fine, though right now if they're using |
@@ -35,12 +35,13 @@ def process(*) #:nodoc: | |||
module ClassMethods | |||
def view_context_class | |||
@view_context_class ||= begin | |||
routes = respond_to?(:_routes) && _routes | |||
include_path_helpers = self.supports_relative_path? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can drop the self
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@schneems I missed the discussion. Will check. |
Even if this doesn't have an implicit host, why does _path must be deprecated? The partial path should still work and it's up to user if and how they want to use it. |
How so? You'll send an email with an unclickable link. If you need this functionality you can use a URL helper and pass in only_path: true. |
What about forcing |
The Any comments or questions on implementation? |
|
# Rails.application.routes.url_helpers.url_for(args) | ||
@_routes = routes | ||
class << self | ||
delegate :url_for, :optimize_routes_generation?, :to => '@_routes' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick but could we use 1.9 hash syntax here please ? :-) Thanks for the patch so far!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, i also updated the hashes in define_named_route_methods
for consistency
I agree with this PR, I think it's a non-obvious thing that newer Rails devs may get caught by and not understand why things aren't working for their end users. |
I think there should still be a way to get at the bare paths. For example: |
@schneems thanks for the patch, will try to review soon! |
Hi @schneems! I had a look at the patch. Looks good to me, I like the overall idea of separating URL and path modules. Regarding the implementation I only have some minor remarks:
Let's iterate a little bit and done! |
if include_path_helpers | ||
path_helpers = routes.named_routes.path_helpers_module | ||
else | ||
warning_block = ->(name) {"The method `#{name}` cannot be used here as relative links are not supported. Use `#{name.sub(/_path$/, '_url')}` instead"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The message also needs to tell the user what to do when he indeed needs only the path. For example, xxx_url only_path: true
(but please check if that actually works, didn't test it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm _path
then I would agree, but here it's such a minority it will distract and confuse. The statement is factually correct, tells how to get rid of the error/deprecation and does not assume how it will be used. Pointing someone to a _url
is still correct. The error message is not a complete substitute for docs.
The 1% of time people need this non working url, it's in the docs for _url
helpers and is extremely google-able.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but does only_path
actually still work? That's what I'm most concerned about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this doesn't touch the implementation of *_url
only *_path
Moving this logic to the railtie is the only component i'm having problems with. The behavior is deeply nested inside of action view. We need to get this state information to https://github.com/rails/rails/blob/master/actionview/lib/action_view/rendering.rb#L43-L44 somehow. This is included in ActionMailer directly through ActionView::Layouts https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb#L416 This seems like a likely place to add logic, but this doesn't affect path helpers in the view (not actually sure what it is doing): https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/railtie.rb#L33 Do you have any ideas or thoughts on how to move this logic to the railtie? cc @sgrif
Updated to proper naming
I'm fine with this, changed to a boolean
Updated to use this technique instead of module injection.
Updated to mention this behavior
Done |
For the archives, we've discussed by email adding the same behavior to mailer instances (in addition to their templates). @schneems I believe we are close. Would you mind doing a couple of last small edits?
Could do that myself after pushing, but if you didn't mind the commit would be more round. |
LGTM |
Email does not support relative links since there is no implicit host. Therefore all links inside of emails must be fully qualified URLs. All path helpers are now deprecated. When removed, the error will give early indication to developers to use `*_url` methods instead. Currently if a developer uses a `*_path` helper, their tests and `mail_view` will not catch the mistake. The only way to see the error is by sending emails in production. Preventing sending out emails with non-working path's is the desired end goal of this PR. Currently path helpers are mixed-in to controllers (the ActionMailer::Base acts as a controller). All `*_url` and `*_path` helpers are made available through the same module. This PR separates this behavior into two modules so we can extend the `*_path` methods to add a Deprecation to them. Once deprecated we can use this same area to raise a NoMethodError and add an informative message directing the developer to use `*_url` instead. The module with warnings is only mixed in when a controller returns false from the newly added `supports_relative_path?`. Paired @sgrif & @schneems
There were a ton of merge conflicts introduced in the last 24 hours (https://github.com/rails/rails/commits/master/actionpack/lib/action_dispatch/routing/route_set.rb). I fixed those. Removed double "instead". Wrote a different last paragraph for the guide. Also had to modify a test that was asserting *_url methods cannot be used directly in mailers. Test introduced 4 years ago, I don't believe the behavior it was asserting was valid. Looks like build is now green. |
Looking good! @schneems you've devoted a lot of time to this PR, since the first discussions in the mailing list to the (not easy) patch and later revisions. That was awesome and really appreciated, thanks so much for working on this. |
…h_methods Deprecate `*_path` methods in mailers
Email does not support relative links since there is no implicit host. Therefore all links inside of emails must be fully qualified URLs. All path helpers are now deprecated. When removed, the error will give early indication to developers to use
*_url
methods instead.Currently if a developer uses a
*_path
helper, their tests andmail_view
will not catch the mistake. The only way to see the error is by sending emails in production. Preventing sending out emails with non-working path's is the desired end goal of this PR.Currently path helpers are mixed-in to controllers (the ActionMailer::Base acts as a controller). All
*_url
and*_path
helpers are made available through the same module. This PR separates this behavior into two modules so we can extend the*_path
methods to add a Deprecation to them. Once deprecated we can use this same area to raise a NoMethodError and add an informative message directing the developer to use*_url
instead.The module with warnings is only mixed in when a controller returns false from the newly added
supports_relative_path?
.Paired @sgrif & @schneems