diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb index 517936bc96..e8ba1de40e 100644 --- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb +++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb @@ -42,6 +42,18 @@ module ActionDispatch # # edit_polymorphic_path(@post) # => "/posts/1/edit" # polymorphic_path(@post, :format => :pdf) # => "/posts/1.pdf" + # + # == Using with mounted engines + # + # If you use mounted engine, there is a possibility that you will need to use + # polymorphic_url pointing at engine's routes. To do that, just pass proxy used + # to reach engine's routes as a first argument: + # + # For example: + # + # polymorphic_url([blog, @post]) # it will call blog.post_path(@post) + # form_for([blog, @post]) # => "/blog/posts/1 + # module PolymorphicRoutes # Constructs a call to a named RESTful route for the given record and returns the # resulting URL string. For example: @@ -78,6 +90,9 @@ module ActionDispatch def polymorphic_url(record_or_hash_or_array, options = {}) if record_or_hash_or_array.kind_of?(Array) record_or_hash_or_array = record_or_hash_or_array.compact + if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy) + proxy = record_or_hash_or_array.shift + end record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1 end @@ -111,7 +126,11 @@ module ActionDispatch args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options end - url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args) + if proxy + proxy.send(named_route, *args) + else + url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args) + end end # Returns the path component of a URL for the given record. It uses diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index 94b8a8c7c3..23c9fb839e 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -57,6 +57,14 @@ class PolymorphicRoutesTest < ActionController::TestCase @blog_blog = Blog::Blog.new end + def test_passing_routes_proxy + with_namespaced_routes(:blog) do + proxy = ActionDispatch::Routing::RoutesProxy.new(_routes, self) + @blog_post.save + assert_equal "http://example.com/posts/#{@blog_post.id}", polymorphic_url([proxy, @blog_post]) + end + end + def test_namespaced_model with_namespaced_routes(:blog) do @blog_post.save diff --git a/railties/test/railties/mounted_engine_test.rb b/railties/test/railties/mounted_engine_test.rb index be5bb30a9a..1df6326d26 100644 --- a/railties/test/railties/mounted_engine_test.rb +++ b/railties/test/railties/mounted_engine_test.rb @@ -18,6 +18,7 @@ module ApplicationTests match "/engine_route" => "application_generating#engine_route" match "/engine_route_in_view" => "application_generating#engine_route_in_view" match "/url_for_engine_route" => "application_generating#url_for_engine_route" + match "/polymorphic_route" => "application_generating#polymorphic_route" scope "/:user", :user => "anonymous" do mount Blog::Engine => "/blog" end @@ -25,6 +26,26 @@ module ApplicationTests end RUBY + @plugin.write "app/models/blog/post.rb", <<-RUBY + module Blog + class Post + extend ActiveModel::Naming + + def id + 44 + end + + def to_param + id.to_s + end + + def new_record? + false + end + end + end + RUBY + @plugin.write "lib/blog.rb", <<-RUBY module Blog class Engine < ::Rails::Engine @@ -78,6 +99,10 @@ module ApplicationTests def url_for_engine_route render :text => blog.url_for(:controller => "blog/posts", :action => "index", :user => "john", :only_path => true) end + + def polymorphic_route + render :text => polymorphic_url([blog, Blog::Post.new]) + end end RUBY @@ -141,6 +166,11 @@ module ApplicationTests script_name "/foo" get "/someone/blog/generate_application_route", {}, 'SCRIPT_NAME' => '/foo' assert_equal "/foo/", last_response.body + reset_script_name! + + # test polymorphic routes + get "/polymorphic_route" + assert_equal "http://example.org/anonymous/blog/posts/44", last_response.body end end end