aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2008-04-01 00:50:09 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2008-04-01 00:50:09 +0000
commit9cc478a2547bec5b72fa2a4b36b2f8e627373a74 (patch)
tree5f23c1449d7701acdee3b3f411412634f042b691 /actionpack
parent2681d55e407233c126ff8f0a5956c302b3acfb91 (diff)
downloadrails-9cc478a2547bec5b72fa2a4b36b2f8e627373a74.tar.gz
rails-9cc478a2547bec5b72fa2a4b36b2f8e627373a74.tar.bz2
rails-9cc478a2547bec5b72fa2a4b36b2f8e627373a74.zip
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
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/lib/action_view/partial_template.rb13
-rw-r--r--actionpack/lib/action_view/partials.rb32
-rw-r--r--actionpack/test/controller/fake_models.rb6
-rw-r--r--actionpack/test/controller/new_render_test.rb20
5 files changed, 63 insertions, 10 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 5dab228866..0d7e2ae5cd 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Support render :partial => collection of heterogeneous elements. #11491 [Zach Dennis]
+
* Avoid remote_ip spoofing. [Brian Candler]
* Added support for regexp flags like ignoring case in the :requirements part of routes declarations #11421 [NeilW]
diff --git a/actionpack/lib/action_view/partial_template.rb b/actionpack/lib/action_view/partial_template.rb
index a470c915cd..7d9c59a41c 100644
--- a/actionpack/lib/action_view/partial_template.rb
+++ b/actionpack/lib/action_view/partial_template.rb
@@ -7,7 +7,7 @@ module ActionView #:nodoc:
@path, @variable_name = extract_partial_name_and_path(view, partial_path)
super(view, @path, true, locals)
add_object_to_local_assigns!(object)
-
+
# This is needed here in order to compile template with knowledge of 'counter'
initialize_counter
@@ -24,11 +24,18 @@ module ActionView #:nodoc:
def render_member(object)
@locals[@counter_name] += 1
@locals[:object] = @locals[@variable_name] = object
- render
+ returning render do
+ @locals.delete(@variable_name)
+ @locals.delete(:object)
+ end
end
+ def counter=(num)
+ @locals[@counter_name] = num
+ end
+
private
-
+
def add_object_to_local_assigns!(object)
@locals[:object] ||=
@locals[@variable_name] ||=
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb
index 7f1963fb29..a92b05508a 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/partials.rb
@@ -113,9 +113,8 @@ module ActionView
render_partial(builder_partial_path, object_assigns, (local_assigns || {}).merge(builder_partial_path.to_sym => partial_path))
when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Associations::HasManyThroughAssociation
if partial_path.any?
- path = ActionController::RecordIdentifier.partial_path(partial_path.first)
collection = partial_path
- render_partial_collection(path, collection, nil, local_assigns)
+ render_partial_collection(nil, collection, nil, local_assigns)
else
""
end
@@ -126,15 +125,34 @@ module ActionView
def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
return " " if collection.empty?
-
+
local_assigns = local_assigns ? local_assigns.clone : {}
- template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
-
spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
-
+
+ if partial_path.nil?
+ render_partial_collection_with_unknown_partial_path(collection, local_assigns, spacer)
+ else
+ render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, spacer)
+ end.join(spacer)
+ end
+
+ def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, spacer)
+ template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
collection.map do |element|
template.render_member(element)
- end.join(spacer)
+ end
+ end
+
+ def render_partial_collection_with_unknown_partial_path(collection, local_assigns, spacer)
+ templates = Hash.new
+ i = 0
+ collection.map do |element|
+ partial_path = ActionController::RecordIdentifier.partial_path(element)
+ template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
+ template.counter = i
+ i += 1
+ template.render_member(element)
+ end
end
end
end
diff --git a/actionpack/test/controller/fake_models.rb b/actionpack/test/controller/fake_models.rb
index 2761b09f2f..7420579ed8 100644
--- a/actionpack/test/controller/fake_models.rb
+++ b/actionpack/test/controller/fake_models.rb
@@ -3,3 +3,9 @@ class Customer < Struct.new(:name, :id)
id.to_s
end
end
+
+class BadCustomer < Customer
+end
+
+class GoodCustomer < Customer
+end
diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb
index 0f14de54b1..342e2e7f87 100644
--- a/actionpack/test/controller/new_render_test.rb
+++ b/actionpack/test/controller/new_render_test.rb
@@ -163,6 +163,21 @@ class NewRenderTestController < ActionController::Base
render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
end
+ def partial_collection_shorthand_with_different_types_of_records
+ render :partial => [
+ BadCustomer.new("mark"),
+ GoodCustomer.new("craig"),
+ BadCustomer.new("john"),
+ GoodCustomer.new("zach"),
+ GoodCustomer.new("brandon"),
+ BadCustomer.new("dan") ],
+ :locals => { :greeting => "Bonjour" }
+ end
+
+ def partial_collection_shorthand_with_different_types_of_records_with_counter
+ partial_collection_shorthand_with_different_types_of_records
+ end
+
def empty_partial_collection
render :partial => "customer", :collection => []
end
@@ -741,6 +756,11 @@ EOS
assert_equal "Bonjour: davidBonjour: mary", @response.body
end
+ def test_partial_collection_shorthand_with_different_types_of_records
+ get :partial_collection_shorthand_with_different_types_of_records
+ assert_equal "Bonjour bad customer: mark1Bonjour good customer: craig2Bonjour bad customer: john3Bonjour good customer: zach4Bonjour good customer: brandon5Bonjour bad customer: dan6", @response.body
+ end
+
def test_empty_partial_collection
get :empty_partial_collection
assert_equal " ", @response.body