Skip to content

Commit 9685080

Browse files
committed
let mailer templates generate URLs by default [Xavier Noria, Richard Schneeman]
1 parent cdd90f3 commit 9685080

7 files changed

Lines changed: 107 additions & 12 deletions

File tree

actionmailer/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* `link_to` and `url_for` generate URLs by default in templates, it is no
2+
longer needed to pass `only_path: false`.
3+
4+
Fixes #16497 and #16589.
5+
6+
*Xavier Noria*, *Richard Schneeman*
7+
18
* Attachments can be added while rendering the mail template.
29

310
Fixes #16974.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%= url_for(@options) %> <%= @url %>

actionmailer/test/url_test.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,32 @@ def signed_up_with_url(recipient)
2323
mail(to: recipient, subject: "[Signed up] Welcome #{recipient}",
2424
from: "system@loudthinking.com", date: Time.local(2004, 12, 12))
2525
end
26+
27+
def exercise_url_for(options)
28+
@options = options
29+
@url = url_for(@options)
30+
mail(from: 'from@example.com', to: 'to@example.com', subject: 'subject')
31+
end
2632
end
2733

2834
class ActionMailerUrlTest < ActionMailer::TestCase
35+
class DummyModel
36+
def self.model_name
37+
OpenStruct.new(route_key: 'dummy_model')
38+
end
39+
40+
def persisted?
41+
false
42+
end
43+
44+
def model_name
45+
self.class.model_name
46+
end
47+
48+
def to_model
49+
self
50+
end
51+
end
2952

3053
def encode( text, charset="UTF-8" )
3154
quoted_printable( text, charset )
@@ -40,10 +63,47 @@ def new_mail( charset="UTF-8" )
4063
mail
4164
end
4265

66+
def assert_url_for(expected, options, relative: false)
67+
expected = "http://www.basecamphq.com#{expected}" if expected.start_with?('/') && !relative
68+
urls = UrlTestMailer.exercise_url_for(options).body.to_s.chomp.split
69+
70+
assert_equal expected, urls.first
71+
assert_equal expected, urls.second
72+
end
73+
4374
def setup
4475
@recipient = 'test@localhost'
4576
end
4677

78+
def test_url_for
79+
UrlTestMailer.delivery_method = :test
80+
81+
AppRoutes.draw do
82+
get ':controller(/:action(/:id))'
83+
get '/welcome' => 'foo#bar', as: 'welcome'
84+
get '/dummy_model' => 'foo#baz', as: 'dummy_model'
85+
end
86+
87+
# string
88+
assert_url_for 'http://foo/', 'http://foo/'
89+
90+
# symbol
91+
assert_url_for '/welcome', :welcome
92+
93+
# hash
94+
assert_url_for '/a/b/c', controller: 'a', action: 'b', id: 'c'
95+
assert_url_for '/a/b/c', {controller: 'a', action: 'b', id: 'c', only_path: true}, relative: true
96+
97+
# model
98+
assert_url_for '/dummy_model', DummyModel.new
99+
100+
# class
101+
assert_url_for '/dummy_model', DummyModel
102+
103+
# array
104+
assert_url_for '/dummy_model' , [DummyModel]
105+
end
106+
47107
def test_signed_up_with_url
48108
UrlTestMailer.delivery_method = :test
49109

actionpack/lib/action_dispatch/routing/route_set.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ def #{name}
457457
RUBY
458458
end
459459

460-
def url_helpers(include_path_helpers = true)
460+
def url_helpers(supports_path = true)
461461
routes = self
462462

463463
Module.new do
@@ -484,7 +484,7 @@ def url_options; {}; end
484484
# named routes...
485485
include url_helpers
486486

487-
if include_path_helpers
487+
if supports_path
488488
path_helpers = routes.named_routes.path_helpers_module
489489
else
490490
path_helpers = routes.named_routes.path_helpers_module(true)
@@ -502,6 +502,10 @@ def url_options; {}; end
502502
# UrlFor (included in this module) add extra
503503
# conveniences for working with @_routes.
504504
define_method(:_routes) { @_routes || routes }
505+
506+
define_method(:_generate_paths_by_default) do
507+
supports_path
508+
end
505509
end
506510
end
507511

actionpack/lib/action_dispatch/routing/url_for.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ def _with_routes(routes)
184184
def _routes_context
185185
self
186186
end
187+
188+
private
189+
190+
def _generate_paths_by_default
191+
true
192+
end
187193
end
188194
end
189195
end

actionview/lib/action_view/rendering.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ def process(*) #:nodoc:
3535
module ClassMethods
3636
def view_context_class
3737
@view_context_class ||= begin
38-
include_path_helpers = supports_path?
38+
supports_path = supports_path?
3939
routes = respond_to?(:_routes) && _routes
4040
helpers = respond_to?(:_helpers) && _helpers
4141

4242
Class.new(ActionView::Base) do
4343
if routes
44-
include routes.url_helpers(include_path_helpers)
44+
include routes.url_helpers(supports_path)
4545
include routes.mounted_helpers
4646
end
4747

actionview/lib/action_view/routing_url_for.rb

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,38 @@ def url_for(options = nil)
8080
when String
8181
options
8282
when nil
83-
super({:only_path => true})
83+
super(only_path: _generate_paths_by_default)
8484
when Hash
8585
options = options.symbolize_keys
86-
options[:only_path] = options[:host].nil? unless options.key?(:only_path)
86+
unless options.key?(:only_path)
87+
if options[:host].nil?
88+
options[:only_path] = _generate_paths_by_default
89+
else
90+
options[:only_path] = false
91+
end
92+
end
93+
8794
super(options)
8895
when :back
8996
_back_url
90-
when Symbol
91-
ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_string_call self, options
9297
when Array
93-
polymorphic_path(options, options.extract_options!)
94-
when Class
95-
ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_class_call self, options
98+
if _generate_paths_by_default
99+
polymorphic_path(options, options.extract_options!)
100+
else
101+
polymorphic_url(options, options.extract_options!)
102+
end
96103
else
97-
ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call self, options
104+
method = _generate_paths_by_default ? :path : :url
105+
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method)
106+
107+
case options
108+
when Symbol
109+
builder.handle_string_call(self, options)
110+
when Class
111+
builder.handle_class_call(self, options)
112+
else
113+
builder.handle_model_call(self, options)
114+
end
98115
end
99116
end
100117

0 commit comments

Comments
 (0)