From 5a7e501d27d991fea7aa6d19b15a8d3280430da1 Mon Sep 17 00:00:00 2001 From: Justin French Date: Sun, 28 Dec 2008 00:14:40 +1100 Subject: [PATCH] Added a :style option for rendering partials with RecordIdentifier, allowing the same object to be rendered with a different partial to suit different rendering situations. The value of :style is used to add a suffix to the standard partial name provided by RecordIdentifier#partial_path. Examples: Before: <%= render :partial => "posts/post_summary", :locals => { :post => @post } %> After: <%= render :partial => @post, :style => :summary %> Before: <%= render :partial => "posts/post_summary", :collection => @posts, :as => :post %> After: <%= render :partial => @posts, :style => :summary %> This also heavily reduces the effort involved if you want to use a "summary" partial on a collection of objects with differing classes, like records from a table with STI. --- actionpack/lib/action_view/partials.rb | 16 ++++++++++++- actionpack/test/controller/render_test.rb | 24 ++++++++++++++++++++ .../test/fixtures/customers/_customer_summary.erb | 1 + 3 files changed, 40 insertions(+), 1 deletions(-) create mode 100644 actionpack/test/fixtures/customers/_customer_summary.erb diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 59e82b9..8503e1b 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -59,6 +59,16 @@ module ActionView # # <%= render :partial => "posts/post", :collection => @posts %> # <%= render :partial => @posts %> # + # If you want to use different partials to render the same object in different situations (eg + # posts/post_summary or posts/post_search_result), you can pass in a :style option as a String or + # Symbol, which will be used to add a suffix to the standard partial name. Examples: + # + # # Instead of <%= render :partial => "posts/post_summary", :locals => { :post => @post } %> + # <%= render :partial => @post, :style => :summary %> + # + # # Instead of <%= render :partial => "posts/post_summary", :collection => @posts, :as => :post %> + # <%= render :partial => @posts, :style => :summary %> + # # == Rendering the default case # # If you're not going to be using any of the options like collections or layouts, you can also use the short-hand @@ -191,8 +201,10 @@ module ActionView render_partial_collection(options.except(:partial).merge(:collection => partial_path)) else object = partial_path + partial = ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path) + partial += "_#{options[:style]}" unless options[:style].blank? render_partial( - :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path), + :partial => partial, :object => object, :locals => local_assigns ) @@ -206,11 +218,13 @@ module ActionView spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : '' local_assigns = options[:locals] ? options[:locals].clone : {} as = options[:as] + style = options[:style] index = 0 options[:collection].map do |object| _partial_path ||= partial || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path) + _partial_path += "_#{style}" unless style.blank? template = _pick_partial_template(_partial_path) local_assigns[template.counter_name] = index result = template.render_partial(self, object, local_assigns.dup, as) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 5fd41d8..bd61261 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1,5 +1,6 @@ require 'abstract_unit' require 'controller/fake_models' +require 'active_record_unit' module Fun class GamesController < ActionController::Base @@ -575,6 +576,14 @@ class TestController < ActionController::Base def partial_with_counter render :partial => "counter", :locals => { :counter_counter => 5 } end + + def partial_with_shorthand + render :partial => Customer.new("david"), :locals => { :greeting => "Hello" } + end + + def partial_with_shorthand_and_style + render :partial => Customer.new("david"), :style => :summary, :locals => { :greeting => "Hello" } + end def partial_with_locals render :partial => "customer", :locals => { :customer => Customer.new("david") } @@ -611,6 +620,10 @@ class TestController < ActionController::Base def partial_collection_shorthand_with_locals render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" } end + + def partial_collection_shorthand_with_style + render :partial => [ Customer.new("david"), Customer.new("mary") ], :style => :summary + end def partial_collection_shorthand_with_different_types_of_records render :partial => [ @@ -1342,6 +1355,11 @@ class RenderTest < ActionController::TestCase get :partial_with_locals assert_equal "Hello: david", @response.body end + + def test_partial_with_shorthand + get :partial_with_shorthand + assert_equal "Hello: david", @response.body + end def test_partial_with_form_builder get :partial_with_form_builder @@ -1389,6 +1407,12 @@ class RenderTest < ActionController::TestCase assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0 end + def test_partial_collection_shorthand_with_style + get :partial_collection_shorthand_with_style + assert_equal "customer summarycustomer summary", @response.body + assert_template :partial => 'customers/_customer', :count => 2 + 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: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body diff --git a/actionpack/test/fixtures/customers/_customer_summary.erb b/actionpack/test/fixtures/customers/_customer_summary.erb new file mode 100644 index 0000000..aa103da --- /dev/null +++ b/actionpack/test/fixtures/customers/_customer_summary.erb @@ -0,0 +1 @@ +customer summary \ No newline at end of file -- 1.5.5.3