public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Support render :partial => collection of heterogeneous elements. Closes 
#11491.


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9177 
5ecf4fe2-1ee6-0310-87b1-e25e094e27de
jeremy (author)
Mon Mar 31 17:50:09 -0700 2008
commit  9cc478a2547bec5b72fa2a4b36b2f8e627373a74
tree    5f23c1449d7701acdee3b3f411412634f042b691
parent  2681d55e407233c126ff8f0a5956c302b3acfb91
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 *SVN*
0
 
0
+* Support render :partial => collection of heterogeneous elements. #11491 [Zach Dennis]
0
+
0
 * Avoid remote_ip spoofing. [Brian Candler]
0
 
0
 * Added support for regexp flags like ignoring case in the :requirements part of routes declarations #11421 [NeilW]
...
7
8
9
10
 
11
12
13
...
24
25
26
27
 
 
 
 
28
29
 
 
 
 
30
31
 
32
33
34
...
7
8
9
 
10
11
12
13
...
24
25
26
 
27
28
29
30
31
32
33
34
35
36
37
 
38
39
40
41
0
@@ -7,7 +7,7 @@ module ActionView #:nodoc:
0
       @path, @variable_name = extract_partial_name_and_path(view, partial_path)
0
       super(view, @path, true, locals)
0
       add_object_to_local_assigns!(object)
0
-
0
+
0
       # This is needed here in order to compile template with knowledge of 'counter'
0
       initialize_counter
0
       
0
@@ -24,11 +24,18 @@ module ActionView #:nodoc:
0
     def render_member(object)
0
       @locals[@counter_name] += 1
0
       @locals[:object] = @locals[@variable_name] = object
0
- render
0
+ returning render do
0
+ @locals.delete(@variable_name)
0
+ @locals.delete(:object)
0
+ end
0
     end
0
     
0
+ def counter=(num)
0
+ @locals[@counter_name] = num
0
+ end
0
+
0
     private
0
-
0
+
0
     def add_object_to_local_assigns!(object)
0
       @locals[:object] ||=
0
         @locals[@variable_name] ||=
...
113
114
115
116
117
118
 
119
120
121
...
126
127
128
129
 
130
131
132
133
134
 
 
 
 
 
 
 
 
 
 
135
136
137
 
 
 
 
 
 
 
 
 
 
 
 
 
138
139
140
...
113
114
115
 
116
 
117
118
119
120
...
125
126
127
 
128
129
 
 
130
 
131
132
133
134
135
136
137
138
139
140
141
142
 
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
0
@@ -113,9 +113,8 @@ module ActionView
0
           render_partial(builder_partial_path, object_assigns, (local_assigns || {}).merge(builder_partial_path.to_sym => partial_path))
0
         when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Associations::HasManyThroughAssociation
0
           if partial_path.any?
0
- path = ActionController::RecordIdentifier.partial_path(partial_path.first)
0
             collection = partial_path
0
- render_partial_collection(path, collection, nil, local_assigns)
0
+ render_partial_collection(nil, collection, nil, local_assigns)
0
           else
0
             ""
0
           end
0
@@ -126,15 +125,34 @@ module ActionView
0
 
0
       def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
0
         return " " if collection.empty?
0
-
0
+
0
         local_assigns = local_assigns ? local_assigns.clone : {}
0
- template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
0
-
0
         spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
0
-
0
+
0
+ if partial_path.nil?
0
+ render_partial_collection_with_unknown_partial_path(collection, local_assigns, spacer)
0
+ else
0
+ render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, spacer)
0
+ end.join(spacer)
0
+ end
0
+
0
+ def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, spacer)
0
+ template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
0
         collection.map do |element|
0
           template.render_member(element)
0
- end.join(spacer)
0
+ end
0
+ end
0
+
0
+ def render_partial_collection_with_unknown_partial_path(collection, local_assigns, spacer)
0
+ templates = Hash.new
0
+ i = 0
0
+ collection.map do |element|
0
+ partial_path = ActionController::RecordIdentifier.partial_path(element)
0
+ template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
0
+ template.counter = i
0
+ i += 1
0
+ template.render_member(element)
0
+ end
0
       end
0
   end
0
 end
...
3
4
5
 
 
 
 
 
 
...
3
4
5
6
7
8
9
10
11
0
@@ -3,3 +3,9 @@ class Customer < Struct.new(:name, :id)
0
     id.to_s
0
   end
0
 end
0
+
0
+class BadCustomer < Customer
0
+end
0
+
0
+class GoodCustomer < Customer
0
+end
...
163
164
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
167
168
...
741
742
743
 
 
 
 
 
744
745
746
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
756
757
758
759
760
761
762
763
764
765
766
0
@@ -163,6 +163,21 @@ class NewRenderTestController < ActionController::Base
0
     render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
0
   end
0
 
0
+ def partial_collection_shorthand_with_different_types_of_records
0
+ render :partial => [
0
+ BadCustomer.new("mark"),
0
+ GoodCustomer.new("craig"),
0
+ BadCustomer.new("john"),
0
+ GoodCustomer.new("zach"),
0
+ GoodCustomer.new("brandon"),
0
+ BadCustomer.new("dan") ],
0
+ :locals => { :greeting => "Bonjour" }
0
+ end
0
+
0
+ def partial_collection_shorthand_with_different_types_of_records_with_counter
0
+ partial_collection_shorthand_with_different_types_of_records
0
+ end
0
+
0
   def empty_partial_collection
0
     render :partial => "customer", :collection => []
0
   end
0
@@ -741,6 +756,11 @@ EOS
0
     assert_equal "Bonjour: davidBonjour: mary", @response.body
0
   end
0
 
0
+ def test_partial_collection_shorthand_with_different_types_of_records
0
+ get :partial_collection_shorthand_with_different_types_of_records
0
+ assert_equal "Bonjour bad customer: mark1Bonjour good customer: craig2Bonjour bad customer: john3Bonjour good customer: zach4Bonjour good customer: brandon5Bonjour bad customer: dan6", @response.body
0
+ end
0
+
0
   def test_empty_partial_collection
0
     get :empty_partial_collection
0
     assert_equal " ", @response.body

Comments

    No one has commented yet.