aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb21
-rw-r--r--actionpack/test/activerecord/polymorphic_routes_test.rb8
-rw-r--r--railties/test/railties/mounted_engine_test.rb30
3 files changed, 58 insertions, 1 deletions
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