diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 3f77234d03..c67592374e 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,6 +1,6 @@ *SVN* -* Resources: url_for([parent, child]) generates /parents/1/children/2 for the nested resource. Likewise with the other simply helpful methods like form_for and link_to. #6432 [mhw, Jonathan Vaught] +* Resources: url_for([parent, child]) generates /parents/1/children/2 for the nested resource. Likewise with the other simply helpful methods like form_for and link_to. #6432 [mhw, Jonathan Vaught, lotswholetime] * Assume html format when rendering partials in RJS. #8076 [Rick] diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index 6c21bc27c5..d6c57d1207 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -3,7 +3,14 @@ module ActionController def polymorphic_url(record_or_hash_or_array, options = {}) record = extract_record(record_or_hash_or_array) - args = [] + args = case record_or_hash_or_array + when Hash: [record_or_hash_or_array[:id]] + when Array: record_or_hash_or_array.dup + else [record_or_hash_or_array] + end + + args.pop # Remove the base record; we only need it in one case + inflection = case when options[:action] == "new" @@ -11,10 +18,10 @@ module ActionController when record.respond_to?(:new_record?) && record.new_record? :plural else - args = [record_or_hash_or_array] + args.push(record) # Put the base record back in :singular end - + named_route = build_named_route_call(record_or_hash_or_array, inflection, options) send(named_route, *args) end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 1886c7ab15..b003b69bb1 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -166,13 +166,12 @@ module ActionView when Array object = record_or_name_or_array.last object_name = ActionController::RecordIdentifier.singular_class_name(object) - # apply_form_for_options!(object, options, *record_or_name_or_array) apply_form_for_options!(record_or_name_or_array, options) args.unshift object else object = record_or_name_or_array object_name = ActionController::RecordIdentifier.singular_class_name(object) - apply_form_for_options!([ object ], options) + apply_form_for_options!([object], options) args.unshift object end diff --git a/actionpack/test/controller/polymorphic_routes_test.rb b/actionpack/test/controller/polymorphic_routes_test.rb new file mode 100644 index 0000000000..1d11eeda47 --- /dev/null +++ b/actionpack/test/controller/polymorphic_routes_test.rb @@ -0,0 +1,70 @@ +require File.dirname(__FILE__) + '/../abstract_unit' + +class Article + attr_reader :id + def save; @id = 1 end + def new_record?; @id.nil? end + def name + @id.nil? ? 'new post' : "post ##{@id}" + end +end + +class Comment + attr_reader :id + def post_id; 1 end + def save; @id = 1 end + def new_record?; @id.nil? end + def name + @id.nil? ? 'new comment' : "comment ##{@id}" + end +end + +class Comment::Nested < Comment; end + +class Test::Unit::TestCase + protected + def articles_url + 'http://www.example.com/articles' + end + alias_method :new_article_url, :articles_url + + def article_url(article) + "http://www.example.com/articles/#{article.id}" + end + + def article_comments_url(article) + "http://www.example.com/articles/#{article.id}/comments" + end + + def article_comment_url(article, comment) + "http://www.example.com/articles/#{article.id}/comments/#{comment.id}" + end +end + + +class PolymorphicRoutesTest < Test::Unit::TestCase + include ActionController::PolymorphicRoutes + + def setup + @article = Article.new + @comment = Comment.new + end + + def test_with_record + assert_equal(articles_url, polymorphic_url(@article, :action => 'new')) + assert_equal(articles_url, polymorphic_url(@article)) + @article.save + assert_equal(article_url(@article), polymorphic_url(@article)) + end + + def test_with_hash + @article.save + assert_equal(article_url(@article), polymorphic_url(:id => @article)) + end + + def test_with_array + assert_equal(article_comments_url(@article), polymorphic_url([@article, @comment])) + @comment.save + assert_equal(article_comment_url(@article, @comment), polymorphic_url([@article, @comment])) + end +end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index e83d7e0538..3d8368f700 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -38,6 +38,7 @@ class FormHelperTest < Test::Unit::TestCase include ActionView::Helpers::TextHelper include ActionView::Helpers::ActiveRecordHelper include ActionView::Helpers::RecordIdentificationHelper + include ActionController::PolymorphicRoutes def setup @post = Post.new @@ -636,32 +637,18 @@ class FormHelperTest < Test::Unit::TestCase 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 - - def polymorphic_path(record_or_hash_or_array) - if record_or_hash_or_array.is_a?(Array) - record = record_or_hash_or_array.pop - array = record_or_hash_or_array - else - record = record_or_hash_or_array - array = [ ] - end - - if array.size > 0 - if record.new_record? - "/posts/123/comments" - else - "/posts/123/comments/#{record.id}" - end - else - if record.new_record? - "/posts" - else - "/posts/#{record.id}" - end - end + alias_method :post_comment_path, :comment_path + + def posts_path + "/posts" + end + + def post_path(post) + "/posts/#{post.id}" end end