Skip to content
This repository
Browse code

Fixed polymorphic_url to be able to handle singleton resources.

Example usage:
polymorphic_url([:admin, @user, :blog, @post]) # => admin_user_blog_post_url(@user, @post)

[#461 state:resolved]
  • Loading branch information...
commit bb6e8eea5a8190aaab67da0a7efedb3bb3d9fccb 1 parent a210f50
authored June 20, 2008 jeremy committed June 22, 2008
2  actionpack/CHANGELOG
... ...
@@ -1,5 +1,7 @@
1 1
 *Edge*
2 2
 
  3
+* Fix polymorphic_url with singleton resources.  #461 [Tammer Saleh]
  4
+
3 5
 * Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek]
4 6
 
5 7
 * Added block-call style to link_to [Sam Stephenson/DHH]. Example:
37  actionpack/lib/action_controller/polymorphic_routes.rb
@@ -48,6 +48,9 @@ module PolymorphicRoutes
48 48
     #
49 49
     #   # calls post_url(post)
50 50
     #   polymorphic_url(post) # => "http://example.com/posts/1"
  51
+    #   polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
  52
+    #   polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
  53
+    #   polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
51 54
     #
52 55
     # ==== Options
53 56
     #
@@ -83,8 +86,6 @@ def polymorphic_url(record_or_hash_or_array, options = {})
83 86
         else        [ record_or_hash_or_array ]
84 87
       end
85 88
 
86  
-      args << format if format
87  
-
88 89
       inflection =
89 90
         case
90 91
         when options[:action].to_s == "new"
@@ -96,6 +97,9 @@ def polymorphic_url(record_or_hash_or_array, options = {})
96 97
         else
97 98
           :singular
98 99
         end
  100
+
  101
+      args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
  102
+      args << format if format
99 103
       
100 104
       named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
101 105
       send!(named_route, *args)
@@ -136,11 +140,19 @@ def build_named_route_call(records, namespace, inflection, options = {})
136 140
         else
137 141
           record = records.pop
138 142
           route = records.inject("") do |string, parent|
139  
-            string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
  143
+            if parent.is_a?(Symbol) || parent.is_a?(String)
  144
+              string << "#{parent}_"
  145
+            else
  146
+              string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
  147
+            end
140 148
           end
141 149
         end
142 150
 
143  
-        route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
  151
+        if record.is_a?(Symbol) || record.is_a?(String)
  152
+          route << "#{record}_"
  153
+        else
  154
+          route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
  155
+        end
144 156
 
145 157
         action_prefix(options) + namespace + route + routing_type(options).to_s
146 158
       end
@@ -163,16 +175,17 @@ def extract_format(record_or_hash_or_array, options)
163 175
         end
164 176
       end
165 177
       
  178
+      # Remove the first symbols from the array and return the url prefix
  179
+      # implied by those symbols.
166 180
       def extract_namespace(record_or_hash_or_array)
167  
-        returning "" do |namespace|
168  
-          if record_or_hash_or_array.is_a?(Array)
169  
-            record_or_hash_or_array.delete_if do |record_or_namespace|
170  
-              if record_or_namespace.is_a?(String) || record_or_namespace.is_a?(Symbol)
171  
-                namespace << "#{record_or_namespace}_"
172  
-              end
173  
-            end
174  
-          end  
  181
+        return "" unless record_or_hash_or_array.is_a?(Array)
  182
+
  183
+        namespace_keys = []
  184
+        while (key = record_or_hash_or_array.first) && key.is_a?(String) || key.is_a?(Symbol)
  185
+          namespace_keys << record_or_hash_or_array.shift
175 186
         end
  187
+
  188
+        namespace_keys.map {|k| "#{k}_"}.join
176 189
       end
177 190
   end
178 191
 end
33  actionpack/test/controller/polymorphic_routes_test.rb
@@ -118,6 +118,39 @@ def test_nested_with_array_and_namespace
118 118
       polymorphic_url([:site, :admin, @article, @response, @tag])
119 119
     end
120 120
 
  121
+    def test_nesting_with_array_ending_in_singleton_resource
  122
+      expects(:article_response_url).with(@article)
  123
+      polymorphic_url([@article, :response])
  124
+    end
  125
+
  126
+    def test_nesting_with_array_containing_singleton_resource
  127
+      @tag = Tag.new
  128
+      @tag.save
  129
+      expects(:article_response_tag_url).with(@article, @tag)
  130
+      polymorphic_url([@article, :response, @tag])
  131
+    end
  132
+
  133
+    def test_nesting_with_array_containing_namespace_and_singleton_resource
  134
+      @tag = Tag.new
  135
+      @tag.save
  136
+      expects(:admin_article_response_tag_url).with(@article, @tag)
  137
+      polymorphic_url([:admin, @article, :response, @tag])
  138
+    end
  139
+
  140
+    def test_nesting_with_array_containing_singleton_resource_and_format
  141
+      @tag = Tag.new
  142
+      @tag.save
  143
+      expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf)
  144
+      formatted_polymorphic_url([@article, :response, @tag, :pdf])
  145
+    end
  146
+
  147
+    def test_nesting_with_array_containing_singleton_resource_and_format_option
  148
+      @tag = Tag.new
  149
+      @tag.save
  150
+      expects(:article_response_tag_url).with(@article, @tag, :pdf)
  151
+      polymorphic_url([@article, :response, @tag], :format => :pdf)
  152
+    end
  153
+
121 154
     # TODO: Needs to be updated to correctly know about whether the object is in a hash or not
122 155
     def xtest_with_hash
123 156
       expects(:article_url).with(@article)

0 notes on commit bb6e8ee

Please sign in to comment.
Something went wrong with that request. Please try again.