diff options
author | Piotr Sarnacki <drogus@gmail.com> | 2010-07-14 00:46:42 +0200 |
---|---|---|
committer | Piotr Sarnacki <drogus@gmail.com> | 2010-09-03 22:59:06 +0200 |
commit | b53efd21059b9d829a6617fb5b2dd86754684c60 (patch) | |
tree | 37557320c2de88ac084dc45747cdc243c0385ad2 /actionpack | |
parent | b697ba9fd72ac8701747863b42082e59f13ba678 (diff) | |
download | rails-b53efd21059b9d829a6617fb5b2dd86754684c60.tar.gz rails-b53efd21059b9d829a6617fb5b2dd86754684c60.tar.bz2 rails-b53efd21059b9d829a6617fb5b2dd86754684c60.zip |
Extended url_for to handle specifying which router should be used.
A few examples:
url_for Blog::Engine, :posts_path
url_for Blog::Engine, @post
url_for Blog::Engine, :action => "main", :controller => "index"
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_dispatch/routing/polymorphic_routes.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 24 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/url_for.rb | 45 | ||||
-rw-r--r-- | actionpack/test/dispatch/url_for_test.rb | 52 | ||||
-rw-r--r-- | actionpack/test/dispatch/url_generation_test.rb | 1 | ||||
-rw-r--r-- | actionpack/test/template/form_helper_test.rb | 90 | ||||
-rw-r--r-- | actionpack/test/template/test_test.rb | 2 |
7 files changed, 136 insertions, 80 deletions
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb index fb2118a8d7..15ee7c8051 100644 --- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb +++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb @@ -111,7 +111,7 @@ module ActionDispatch args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options end - send(named_route, *args) + url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args) end # Returns the path component of a URL for the given record. It uses diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 6f182ae652..c94b00257b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -158,10 +158,17 @@ module ActionDispatch # We use module_eval to avoid leaks @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 - def #{selector}(options = nil) # def hash_for_users_url(options = nil) - options ? #{options.inspect}.merge(options) : #{options.inspect} # options ? {:only_path=>false}.merge(options) : {:only_path=>false} - end # end - protected :#{selector} # protected :hash_for_users_url + def #{selector}(*args) + options = args.extract_options! + + if args.any? + options[:_positional_args] = args + options[:_positional_keys] = #{route.segment_keys.inspect} + end + + options ? #{options.inspect}.merge(options) : #{options.inspect} + end + protected :#{selector} END_EVAL helpers << selector end @@ -185,14 +192,7 @@ module ActionDispatch @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 def #{selector}(*args) - options = #{hash_access_method}(args.extract_options!) - - if args.any? - options[:_positional_args] = args - options[:_positional_keys] = #{route.segment_keys.inspect} - end - - url_for(options) + url_for(#{hash_access_method}(*args)) end END_EVAL helpers << selector diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 5da41df485..edcb7f9cbe 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -123,27 +123,40 @@ module ActionDispatch # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok' # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/' # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33' - def url_for(options = nil) - case options - when String - options - when nil, Hash - routes = (options ? options.delete(:routes) : nil) || _routes - - _with_routes(routes) do - routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys) + def url_for(*args) + if args.first.respond_to?(:routes) + app = args.shift + _with_routes(app.routes) do + if args.first.is_a? Symbol + named_route = args.shift + url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args) + else + url_for(*args) + end end else - polymorphic_url(options) + options = args.first + case options + when String + options + when nil, Hash + routes = (options ? options.delete(:routes) : nil) || _routes + _with_routes(routes) do + routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys) + end + else + polymorphic_url(options) + end end end - def _with_routes(routes) - old_routes, @_routes = @_routes, routes - yield - ensure - @_routes = old_routes - end + protected + def _with_routes(routes) + old_routes, @_routes = @_routes, routes + yield + ensure + @_routes = old_routes + end end end end diff --git a/actionpack/test/dispatch/url_for_test.rb b/actionpack/test/dispatch/url_for_test.rb new file mode 100644 index 0000000000..3dc96d27d7 --- /dev/null +++ b/actionpack/test/dispatch/url_for_test.rb @@ -0,0 +1,52 @@ +require 'abstract_unit' + +module UrlForGeneration + class UrlForTest < ActionDispatch::IntegrationTest + + Routes = ActionDispatch::Routing::RouteSet.new + Routes.draw { match "/foo", :to => "my_route_generating#index", :as => :foo } + + class BlogEngine + def self.routes + @routes ||= begin + routes = ActionDispatch::Routing::RouteSet.new + routes.draw do + resources :posts + end + routes + end + end + end + + class Post + extend ActiveModel::Naming + + def to_param + "1" + end + + def self.model_name + klass = "Post" + def klass.name; self end + + ActiveModel::Name.new(klass) + end + end + + include Routes.url_helpers + + test "url_for with named url helpers" do + assert_equal "/posts", url_for(BlogEngine, :posts_path) + end + + test "url_for with polymorphic routes" do + assert_equal "http://www.example.com/posts/1", url_for(BlogEngine, Post.new) + end + + test "url_for with named url helper with arguments" do + assert_equal "/posts/1", url_for(BlogEngine, :post_path, 1) + assert_equal "/posts/1", url_for(BlogEngine, :post_path, :id => 1) + assert_equal "/posts/1.json", url_for(BlogEngine, :post_path, :id => 1, :format => :json) + end + end +end diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb index d491be2f11..2b54bc62b0 100644 --- a/actionpack/test/dispatch/url_generation_test.rb +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -41,3 +41,4 @@ module TestUrlGeneration end end end + diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 9a1fe01872..ec57b6a2ab 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -77,13 +77,35 @@ class FormHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) end + Routes = ActionDispatch::Routing::RouteSet.new + Routes.draw do + resources :posts do + resources :comments + end + + namespace :admin do + resources :posts do + resources :comments + end + end + + match "/foo", :to => "controller#action" + root :to => "main#index" + end + + def _routes + Routes + end + + include Routes.url_helpers + def url_for(object) @url_for_options = object - if object.is_a?(Hash) - "http://www.example.com" - else - super + if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank? + object.merge!(:controller => "main", :action => "index") end + object + super end def test_label @@ -628,7 +650,7 @@ class FormHelperTest < ActionView::TestCase end expected = - "<form accept-charset='UTF-8' action='http://www.example.com' id='create-post' method='post'>" + + "<form accept-charset='UTF-8' action='/' id='create-post' method='post'>" + snowman + "<label for='post_title'>The Title</label>" + "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + @@ -683,7 +705,7 @@ class FormHelperTest < ActionView::TestCase end end - expected = whole_form("http://www.example.com", "create-post", nil, "put") do + expected = whole_form("/", "create-post", nil, "put") do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[secret]' type='hidden' value='0' />" + @@ -702,7 +724,7 @@ class FormHelperTest < ActionView::TestCase end end - expected = whole_form("http://www.example.com", "create-post", nil, :method => "put", :remote => true) do + expected = whole_form("/", "create-post", nil, :method => "put", :remote => true) do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[secret]' type='hidden' value='0' />" + @@ -721,7 +743,7 @@ class FormHelperTest < ActionView::TestCase end end - expected = whole_form("http://www.example.com", nil, nil, :remote => true) do + expected = whole_form("/", nil, nil, :remote => true) do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[secret]' type='hidden' value='0' />" + @@ -738,7 +760,7 @@ class FormHelperTest < ActionView::TestCase concat f.check_box(:secret) end - expected = whole_form("http://www.example.com", "create-post") do + expected = whole_form("/", "create-post") do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[secret]' type='hidden' value='0' />" + @@ -1478,7 +1500,7 @@ class FormHelperTest < ActionView::TestCase end expected = - "<form accept-charset='UTF-8' action='http://www.example.com' id='create-post' method='post'>" + + "<form accept-charset='UTF-8' action='/' id='create-post' method='post'>" + snowman + "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + @@ -1502,7 +1524,7 @@ class FormHelperTest < ActionView::TestCase end expected = - whole_form("http://www.example.com", "create-post") do + whole_form("/", "create-post") do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" @@ -1546,7 +1568,7 @@ class FormHelperTest < ActionView::TestCase txt << %{</div>} end - def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil) + def form_text(action = "/", id = nil, html_class = nil, remote = nil) txt = %{<form accept-charset="UTF-8" action="#{action}"} txt << %{ data-remote="true"} if remote txt << %{ class="#{html_class}"} if html_class @@ -1554,7 +1576,7 @@ class FormHelperTest < ActionView::TestCase txt << %{ method="post">} end - def whole_form(action = "http://www.example.com", id = nil, html_class = nil, options = nil) + def whole_form(action = "/", id = nil, html_class = nil, options = nil) contents = block_given? ? yield : "" if options.is_a?(Hash) @@ -1655,7 +1677,7 @@ class FormHelperTest < ActionView::TestCase assert_deprecated do form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end end - expected = whole_form("http://www.example.com", "some_form", "some_class") + expected = whole_form("/", "some_form", "some_class") assert_dom_equal expected, output_buffer end @@ -1710,14 +1732,14 @@ class FormHelperTest < ActionView::TestCase @comment.save form_for([@post, @comment]) {} - expected = whole_form(comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put") + expected = whole_form(post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put") assert_dom_equal expected, output_buffer end def test_form_for_with_new_object_in_list form_for([@post, @comment]) {} - expected = whole_form(comments_path(@post), "new_comment", "new_comment") + expected = whole_form(post_comments_path(@post), "new_comment", "new_comment") assert_dom_equal expected, output_buffer end @@ -1725,14 +1747,14 @@ class FormHelperTest < ActionView::TestCase @comment.save form_for([:admin, @post, @comment]) {} - expected = whole_form(admin_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put") + expected = whole_form(admin_post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put") assert_dom_equal expected, output_buffer end def test_form_for_with_new_object_and_namespace_in_list form_for([:admin, @post, @comment]) {} - expected = whole_form(admin_comments_path(@post), "new_comment", "new_comment") + expected = whole_form(admin_post_comments_path(@post), "new_comment", "new_comment") assert_dom_equal expected, output_buffer end @@ -1749,38 +1771,6 @@ class FormHelperTest < ActionView::TestCase end protected - def comments_path(post) - "/posts/#{post.id}/comments" - end - alias_method :post_comments_path, :comments_path - - def comment_path(post, comment) - "/posts/#{post.id}/comments/#{comment.id}" - end - alias_method :post_comment_path, :comment_path - - def admin_comments_path(post) - "/admin/posts/#{post.id}/comments" - end - alias_method :admin_post_comments_path, :admin_comments_path - - def admin_comment_path(post, comment) - "/admin/posts/#{post.id}/comments/#{comment.id}" - end - alias_method :admin_post_comment_path, :admin_comment_path - - def posts_path - "/posts" - end - - def post_path(post, options = {}) - if options[:format] - "/posts/#{post.id}.#{options[:format]}" - else - "/posts/#{post.id}" - end - end - def protect_against_forgery? false end diff --git a/actionpack/test/template/test_test.rb b/actionpack/test/template/test_test.rb index 68e790cf46..20c96824d6 100644 --- a/actionpack/test/template/test_test.rb +++ b/actionpack/test/template/test_test.rb @@ -39,7 +39,7 @@ class PeopleHelperTest < ActionView::TestCase with_test_route_set do person = mock(:name => "David") person.class.extend ActiveModel::Naming - expects(:mocha_mock_path).with(person).returns("/people/1") + _routes.url_helpers.expects(:hash_for_mocha_mock_path).with(person).returns("/people/1") assert_equal '<a href="/people/1">David</a>', link_to_person(person) end end |