From be22a8b98f19e94f360f409e784af3eee0445012 Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Sat, 20 Nov 2010 23:32:06 +0700 Subject: [PATCH 1/2] Add `:if_empty` option to PartialRenderer You can now supply a partial name which will be rendered if the collection is nil or empty by using `:if_empty` option. --- actionpack/lib/action_view/partials.rb | 10 ++++++++-- .../lib/action_view/renderer/partial_renderer.rb | 16 ++++++++++------ ...nder_partial_with_record_identification_test.rb | 10 ++++++++++ actionpack/test/template/render_test.rb | 12 ++++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 844c3e9..8dc704e 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -69,12 +69,18 @@ module ActionView # +partial_name_counter+. In the case of the example above, the template would be fed +ad_counter+. # # The :as option may be used when rendering partials. - # + # # You can specify a partial to be rendered between elements via the :spacer_template option. - # The following example will render advertiser/_ad_divider.html.erb between each ad partial: + # The following example will render "advertiser/_ad_divider.html.erb" between each ad partial: # # <%= render :partial => "ad", :collection => @advertisements, :spacer_template => "ad_divider" %> # + # You can also specify a partial which will be rendered when the collection is nil or empty via the + # :if_empty option. The following example will render "advertisers/no_ad.html.erb" instead if + # the +@advertisements+ collection is empty: + # + # <%= render :partial => "ad", :collection => @advertisements, :if_empty => "no_ad" %> + # # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also # just keep domain objects, like Active Records, in there. # diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 317479a..40afe13 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -57,14 +57,18 @@ module ActionView end def render_collection - return nil if @collection.blank? + unless @collection.blank? + if @options[:spacer_template] + spacer = find_template(@options[:spacer_template]).render(@view, @locals) + end - if @options.key?(:spacer_template) - spacer = find_template(@options[:spacer_template]).render(@view, @locals) + result = @template ? collection_with_template : collection_without_template + result.join(spacer).html_safe + else + if @options[:if_empty] + find_template(@options[:if_empty]).render(@view, @locals).html_safe + end end - - result = @template ? collection_with_template : collection_without_template - result.join(spacer).html_safe end def render_partial diff --git a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb index 43c534c..955bf71 100644 --- a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb +++ b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb @@ -44,6 +44,11 @@ class RenderPartialWithRecordIdentificationController < ActionController::Base @developer = Developer.find(1) render :partial => @developer.projects, :spacer_template => 'test/partial_only' end + + def render_with_record_collection_and_empty_template + @developers = Developer.where(:name => "Konata") + render :partial => @developers, :empty_template => "test/partial_only" + end end class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase @@ -85,6 +90,11 @@ class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase assert_equal assigns(:developer).projects.map(&:name).join('only partial'), @response.body end + def test_render_with_record_collection_and_empty_template + get :render_with_record_collection_and_empty_template + assert_equal 'only partial', @response.body + end + def test_rendering_partial_with_has_one_association mascot = Company.find(1).mascot get :render_with_has_one_association diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 8087429..cbafa18 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -164,6 +164,18 @@ module RenderTestCases assert_nil @view.render(:partial => "test/customer", :collection => nil) end + def test_render_partial_collection_with_empty_template + assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ], :if_empty => "test/partial_only") + end + + def test_render_partial_with_empty_template_and_empty_collection + assert_equal "only partial", @view.render(:partial => "test/customer", :collection => [], :if_empty => "test/partial_only") + end + + def test_render_partial_with_empty_template_and_nil_collection + assert_equal "only partial", @view.render(:partial => "test/customer", :collection => nil, :if_empty => "test/partial_only") + end + def test_render_partial_with_nil_values_in_collection assert_equal "Hello: davidHello: Anonymous", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), nil ]) end -- 1.7.3.1