From 3b63a783ab178e3c5258df073e87356113196de7 Mon Sep 17 00:00:00 2001 From: paulreece Date: Sat, 4 Nov 2023 11:43:42 -0400 Subject: [PATCH] This fix allows the polymorphic_method in the HelperMethodBuilder class in polymorphic_routes.rb discern whether or not a singular resource is being passed into it. If it finds a singular resource it will pass in format: nil to the options so that we can have an edited object using the patch method get sent to the proper URL instead of appending a period and number to the end. I believe this is a better implementation than my first try. --- actionpack/CHANGELOG.md | 16 +++++++++++ .../routing/polymorphic_routes.rb | 18 +++++++----- .../test/dispatch/prefix_generation_test.rb | 28 +++++++++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 343300164690a..cddbd4ab60cb9 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -2,4 +2,20 @@ *Hartley McGuire* +* Use the correct path when the resource is singular. + + Before: + ```ruby + edit_author_path + # => /author.1 + ``` + + After: + ```ruby + edit_author_path + # => /author + ``` + + *Paul Reece* + Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/actionpack/CHANGELOG.md) for previous changes. diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb index b92e02e2cad6f..9deaaf2b2f38d 100644 --- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb +++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb @@ -217,7 +217,7 @@ def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, op recipient = record_or_hash_or_array.shift end - method, args = builder.handle_list record_or_hash_or_array + method, args, singular = builder.handle_list record_or_hash_or_array when String, Symbol method, args = builder.handle_string record_or_hash_or_array when Class @@ -226,12 +226,13 @@ def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, op when nil raise ArgumentError, "Nil location provided. Can't build URI." else - method, args = builder.handle_model record_or_hash_or_array + method, args, singular = builder.handle_model record_or_hash_or_array end - if options.empty? + if options.empty? && !singular recipient.public_send(method, *args) else + options[:format] ||= nil recipient.public_send(method, *args, options) end end @@ -261,17 +262,19 @@ def handle_class_call(target, klass) end def handle_model(record) - args = [] - + args = [] + singular = false model = record.to_model + named_route = if model.persisted? + singular = true args << model get_method_for_string model.model_name.singular_route_key else get_method_for_class model end - [named_route, args] + [named_route, args, singular] end def handle_model_call(target, record) @@ -325,7 +328,8 @@ def handle_list(list) route << suffix named_route = prefix + route.join("_") - [named_route, args] + singular = true + [named_route, args, singular] end private diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb index 5ee1a611ca130..3f4599028ab79 100644 --- a/actionpack/test/dispatch/prefix_generation_test.rb +++ b/actionpack/test/dispatch/prefix_generation_test.rb @@ -23,6 +23,24 @@ def to_model; self; end def persisted?; true; end end + class Comment + extend ActiveModel::Naming + + def to_param + "1" + end + + def self.model_name + klass = +"Comment" + def klass.name; self end + + ActiveModel::Name.new(klass) + end + + def to_model; self; end + def persisted?; true; end + end + class WithMountedEngine < ActionDispatch::IntegrationTest class BlogEngine < Rails::Engine routes.draw do @@ -46,6 +64,8 @@ class BlogEngine < Rails::Engine get "/absolute_option_redirect", to: redirect(path: "/foo") get "/absolute_custom_root", to: redirect { |params, request| "/" } get "/absolute_custom_redirect", to: redirect { |params, request| "/foo" } + + resource :comment end end @@ -327,6 +347,14 @@ def setup assert_equal "http://www.example.com/awesome/blog/posts/1", path end + test "[OBJECT] generating engine's route with polymorphic_url from singular resource" do + path = engine_object.polymorphic_path(Comment.new) + assert_equal "/awesome/blog/comment", path + + path = engine_object.polymorphic_url(Comment.new, host: "www.example.com") + assert_equal "http://www.example.com/awesome/blog/comment", path + end + private def verify_redirect(url, status = 301) assert_equal status, response.status