Skip to content

Commit

Permalink
Fixed polymorphic_url to be able to handle singleton resources.
Browse files Browse the repository at this point in the history
Example usage:
polymorphic_url([:admin, @user, :blog, @post]) # => admin_user_blog_post_url(@user, @post)

[#461 state:resolved]
  • Loading branch information
Tammer Saleh authored and jeremy committed Jun 23, 2008
1 parent a210f50 commit bb6e8ee
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 12 deletions.
2 changes: 2 additions & 0 deletions actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*Edge*

* Fix polymorphic_url with singleton resources. #461 [Tammer Saleh]

* Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek]

* Added block-call style to link_to [Sam Stephenson/DHH]. Example:
Expand Down
37 changes: 25 additions & 12 deletions actionpack/lib/action_controller/polymorphic_routes.rb
Expand Up @@ -48,6 +48,9 @@ module PolymorphicRoutes
#
# # calls post_url(post)
# polymorphic_url(post) # => "http://example.com/posts/1"
# polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
# polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
# polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
#
# ==== Options
#
Expand Down Expand Up @@ -83,8 +86,6 @@ def polymorphic_url(record_or_hash_or_array, options = {})
else [ record_or_hash_or_array ]
end

args << format if format

inflection =
case
when options[:action].to_s == "new"
Expand All @@ -96,6 +97,9 @@ def polymorphic_url(record_or_hash_or_array, options = {})
else
:singular
end

args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
args << format if format

named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
send!(named_route, *args)
Expand Down Expand Up @@ -136,11 +140,19 @@ def build_named_route_call(records, namespace, inflection, options = {})
else
record = records.pop
route = records.inject("") do |string, parent|
string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
if parent.is_a?(Symbol) || parent.is_a?(String)
string << "#{parent}_"
else
string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
end
end
end

route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
if record.is_a?(Symbol) || record.is_a?(String)
route << "#{record}_"
else
route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
end

action_prefix(options) + namespace + route + routing_type(options).to_s
end
Expand All @@ -163,16 +175,17 @@ def extract_format(record_or_hash_or_array, options)
end
end

# Remove the first symbols from the array and return the url prefix
# implied by those symbols.
def extract_namespace(record_or_hash_or_array)
returning "" do |namespace|
if record_or_hash_or_array.is_a?(Array)
record_or_hash_or_array.delete_if do |record_or_namespace|
if record_or_namespace.is_a?(String) || record_or_namespace.is_a?(Symbol)
namespace << "#{record_or_namespace}_"
end
end
end
return "" unless record_or_hash_or_array.is_a?(Array)

namespace_keys = []
while (key = record_or_hash_or_array.first) && key.is_a?(String) || key.is_a?(Symbol)
namespace_keys << record_or_hash_or_array.shift
end

namespace_keys.map {|k| "#{k}_"}.join
end
end
end
33 changes: 33 additions & 0 deletions actionpack/test/controller/polymorphic_routes_test.rb
Expand Up @@ -118,6 +118,39 @@ def test_nested_with_array_and_namespace
polymorphic_url([:site, :admin, @article, @response, @tag])
end

def test_nesting_with_array_ending_in_singleton_resource
expects(:article_response_url).with(@article)
polymorphic_url([@article, :response])
end

def test_nesting_with_array_containing_singleton_resource
@tag = Tag.new
@tag.save
expects(:article_response_tag_url).with(@article, @tag)
polymorphic_url([@article, :response, @tag])
end

def test_nesting_with_array_containing_namespace_and_singleton_resource
@tag = Tag.new
@tag.save
expects(:admin_article_response_tag_url).with(@article, @tag)
polymorphic_url([:admin, @article, :response, @tag])
end

def test_nesting_with_array_containing_singleton_resource_and_format
@tag = Tag.new
@tag.save
expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf)
formatted_polymorphic_url([@article, :response, @tag, :pdf])
end

def test_nesting_with_array_containing_singleton_resource_and_format_option
@tag = Tag.new
@tag.save
expects(:article_response_tag_url).with(@article, @tag, :pdf)
polymorphic_url([@article, :response, @tag], :format => :pdf)
end

# TODO: Needs to be updated to correctly know about whether the object is in a hash or not
def xtest_with_hash
expects(:article_url).with(@article)
Expand Down

0 comments on commit bb6e8ee

Please sign in to comment.