Skip to content

Commit db0736a

Browse files
committed
Fix polymorphic_url and polymorphic_path:
- Fix rails#54890 - ### Problem Calling `polyphormic_url` in a integration test or anywhere else when routes may not be loaded yet will result in either crashing or returning a wrong url. ### Details When the routes are not yet loaded, any `resolve` routes are not taken in consideration when calling `polymorphic_url`. ```ruby # config/routes.rb resolve("Post") { "https://example.org" } # test.rb polymorphic_url(@post) # Crash: `post_url` is not defined. ``` ### Solution Load the routes when `polymorphic_mappings` ultimately gets called by `polymorphic_url` https://github.com/rails/rails/blob/42a71a03a0adb465dc49b4e21dec8e0ea29e8e35/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb#L179 ### Side note It's worth to note that `polymorphic_url` was overriden to load the routes, but it only worked if one attempted to call it on the singleton route's url_helpers: ```ruby class MyTest << ActionDispatch::IntegrationTest test "example" do # Works correctly on main Rails.application.routes.url_helpers.polymorphic_url(@post) # Does not work without this patch polymorphic_url(@post) end end ``` I removed the previous implementation because it was at the wrong level.
1 parent 42a71a0 commit db0736a

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

railties/lib/rails/engine/lazy_route_set.rb

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,6 @@ def optimize_routes_generation?
3434
Rails.application&.reload_routes_unless_loaded
3535
super
3636
end
37-
38-
def polymorphic_url(record_or_hash_or_array, options = {})
39-
Rails.application&.reload_routes_unless_loaded
40-
super
41-
end
42-
43-
def polymorphic_path(record_or_hash_or_array, options = {})
44-
Rails.application&.reload_routes_unless_loaded
45-
super
46-
end
4737
end
4838

4939
def initialize(config = DEFAULT_CONFIG)
@@ -68,6 +58,11 @@ def call(req)
6858
super
6959
end
7060

61+
def polymorphic_mappings
62+
Rails.application&.reload_routes_unless_loaded
63+
super
64+
end
65+
7166
def draw(&block)
7267
Rails.application&.reload_routes_unless_loaded
7368
super

railties/test/engine/lazy_route_set_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ class UsersController < ActionController::Base
5252
assert_equal(200, response.first)
5353
end
5454

55+
test "app lazily loads routes when polymorphic_url is called" do
56+
app_file "test/integration/my_test.rb", <<~RUBY
57+
require "test_helper"
58+
59+
class MyTest < ActionDispatch::IntegrationTest
60+
test "polymorphic_url works" do
61+
puts polymorphic_url(Comment.new)
62+
end
63+
end
64+
RUBY
65+
66+
app_file "app/models/comment.rb", <<~RUBY
67+
class Comment
68+
end
69+
RUBY
70+
71+
output = rails("test", "test/integration/my_test.rb")
72+
assert_match("https://example.org", output)
73+
end
74+
5575
test "engine lazily loads routes when making a request" do
5676
require "#{app_path}/config/environment"
5777

@@ -137,6 +157,7 @@ class User < ActiveRecord::Base
137157
138158
resources :products
139159
resources :users, module: "rails/engine/lazy_route_set_test"
160+
resolve("Comment") { "https://example.org" }
140161
141162
mount Plugin::Engine, at: "/plugin"
142163
end

0 commit comments

Comments
 (0)