public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Add :as option to render a collection of partials with a custom local variable 
name. [#509 state:resolved] [Simon Jefford, Pratik Naik]
lifo (author)
Wed Jul 02 08:38:50 -0700 2008
commit  2b43620e3c1352028f19550fcde4632d65cbd191
tree    b28ddcc92eae7fe9ceea11c2f55b1956f5d4efc7
parent  4f75840d72b96fff34d65b59480da7d6c7494120
...
1
2
 
 
 
 
 
 
3
4
5
...
1
2
3
4
5
6
7
8
9
10
11
0
@@ -1,5 +1,11 @@
0
 *Edge*
0
 
0
+* Add :as option to render a collection of partials with a custom local variable name. #509 [Simon Jefford, Pratik Naik]
0
+
0
+  render :partial => 'other_people', :collection => @people, :as => :person
0
+  
0
+  This will let you access objects of @people as 'person' local variable inside 'other_people' partial template.
0
+
0
 * time_zone_select: support for regexp matching of priority zones. Resolves #195 [Ernie Miller]
0
 
0
 * Made ActionView::Base#render_file private [Josh Peek]
...
702
703
704
 
 
 
705
706
707
...
889
890
891
892
 
893
894
895
...
702
703
704
705
706
707
708
709
710
...
892
893
894
 
895
896
897
898
0
@@ -702,6 +702,9 @@ module ActionController #:nodoc:
0
       #   # builds the complete response.
0
       #   render :partial => "person", :collection => @winners
0
       #
0
+      #   # Renders a collection of partials but with a custom local variable name
0
+      #   render :partial => "admin_person", :collection => @winners, :as => :person
0
+      #
0
       #   # Renders the same collection of partials, but also renders the
0
       #   # person_divider partial between each person partial.
0
       #   render :partial => "person", :collection => @winners, :spacer_template => "person_divider"
0
@@ -889,7 +892,7 @@ module ActionController #:nodoc:
0
             if collection = options[:collection]
0
               render_for_text(
0
                 @template.send!(:render_partial_collection, partial, collection,
0
-                options[:spacer_template], options[:locals]), options[:status]
0
+                options[:spacer_template], options[:locals], options[:as]), options[:status]
0
               )
0
             else
0
               render_for_text(
...
252
253
254
255
 
256
257
258
...
252
253
254
 
255
256
257
258
0
@@ -252,7 +252,7 @@ module ActionView #:nodoc:
0
         elsif options[:file]
0
           render_file(options[:file], use_full_path || false, options[:locals])
0
         elsif options[:partial] && options[:collection]
0
-          render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals])
0
+          render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as])
0
         elsif options[:partial]
0
           render_partial(options[:partial], ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals])
0
         elsif options[:inline]
...
1
2
3
 
4
5
 
6
 
7
8
9
...
22
23
24
25
 
26
27
28
 
29
30
31
...
45
46
47
 
48
49
50
...
1
2
 
3
4
 
5
6
7
8
9
10
...
23
24
25
 
26
27
28
29
30
31
32
33
...
47
48
49
50
51
52
53
0
@@ -1,9 +1,10 @@
0
 module ActionView #:nodoc:
0
   class PartialTemplate < Template #:nodoc:
0
-    attr_reader :variable_name, :object
0
+    attr_reader :variable_name, :object, :as
0
 
0
-    def initialize(view, partial_path, object = nil, locals = {})
0
+    def initialize(view, partial_path, object = nil, locals = {}, as = nil)
0
       @view_controller = view.controller if view.respond_to?(:controller)
0
+      @as = as
0
       set_path_and_variable_name!(partial_path)
0
       super(view, @path, true, locals)
0
       add_object_to_local_assigns!(object)
0
@@ -22,10 +23,11 @@ module ActionView #:nodoc:
0
     end
0
 
0
     def render_member(object)
0
-      @locals[:object] = @locals[@variable_name] = object
0
+      @locals[:object] = @locals[@variable_name] = @locals[as] = object
0
 
0
       template = render_template
0
       @locals[@counter_name] += 1
0
+      @locals.delete(as)
0
       @locals.delete(@variable_name)
0
       @locals.delete(:object)
0
 
0
@@ -45,6 +47,7 @@ module ActionView #:nodoc:
0
             else
0
               object
0
             end || @view_controller.instance_variable_get("@#{variable_name}")
0
+        @locals[as] ||= @locals[:object] if as
0
       end
0
 
0
       def set_path_and_variable_name!(partial_path)
...
123
124
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
...
123
124
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
0
@@ -123,32 +123,32 @@ module ActionView
0
         end
0
       end
0
 
0
-      def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
0
+      def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc:
0
         return " " if collection.empty?
0
 
0
         local_assigns = local_assigns ? local_assigns.clone : {}
0
         spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
0
 
0
         if partial_path.nil?
0
-          render_partial_collection_with_unknown_partial_path(collection, local_assigns)
0
+          render_partial_collection_with_unknown_partial_path(collection, local_assigns, as)
0
         else
0
-          render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns)
0
+          render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, as)
0
         end.join(spacer)
0
       end
0
 
0
-      def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns)
0
-        template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
0
+      def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, as)
0
+        template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, as)
0
         collection.map do |element|
0
           template.render_member(element)
0
         end
0
       end
0
 
0
-      def render_partial_collection_with_unknown_partial_path(collection, local_assigns)
0
+      def render_partial_collection_with_unknown_partial_path(collection, local_assigns, as)
0
         templates = Hash.new
0
         i = 0
0
         collection.map do |element|
0
           partial_path = ActionController::RecordIdentifier.partial_path(element, controller.class.controller_path)
0
-          template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
0
+          template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, as)
0
           template.counter = i
0
           i += 1
0
           template.render_member(element)
...
152
153
154
 
 
 
 
155
156
157
...
763
764
765
 
 
 
 
 
766
767
768
...
152
153
154
155
156
157
158
159
160
161
...
767
768
769
770
771
772
773
774
775
776
777
0
@@ -152,6 +152,10 @@ class NewRenderTestController < ActionController::Base
0
     render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
0
   end
0
 
0
+  def partial_collection_with_as
0
+    render :partial => "customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer
0
+  end
0
+
0
   def partial_collection_with_spacer
0
     render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ]
0
   end
0
@@ -763,6 +767,11 @@ EOS
0
     assert_equal "Hello: davidHello: mary", @response.body
0
   end
0
 
0
+  def test_partial_collection_with_as
0
+    get :partial_collection_with_as
0
+    assert_equal "david david davidmary mary mary", @response.body
0
+  end
0
+
0
   def test_partial_collection_with_counter
0
     get :partial_collection_with_counter
0
     assert_equal "david0mary1", @response.body
...
54
55
56
 
 
 
 
 
57
58
59
...
54
55
56
57
58
59
60
61
62
63
64
0
@@ -54,6 +54,11 @@ class ViewRenderTest < Test::Unit::TestCase
0
   def test_render_partial_collection
0
     assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ])
0
   end
0
+  
0
+  def test_render_partial_collection_as
0
+    assert_equal "david david davidmary mary mary", 
0
+      @view.render(:partial => "test/customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer)
0
+  end
0
 
0
   # TODO: The reason for this test is unclear, improve documentation
0
   def test_render_partial_and_fallback_to_layout

Comments

cpjolicoeur Mon Jul 07 09:06:50 -0700 2008

glad this has finally been included into rails core

cpjolicoeur Mon Jul 07 09:07:08 -0700 2008

glad this has finally been included into rails core