There’s also a convenience method for rendering sub templates within the current controller that depends on a single object (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being prefixed with an underscore – as to separate them from regular templates that could be rendered on their own.
In a template for Advertiser#account:
<%= render :partial => "account" %>
This would render “advertiser/_account.rhtml” and pass the instance
variable @account in as a local variable account
to the
template for display.
In another template for Advertiser#buy, we could have:
<%= render :partial => "account", :locals => { :account => @buyer } %> <% for ad in @advertisements %> <%= render :partial => "ad", :locals => { :ad => ad } %> <% end %>
This would first render “advertiser/_account.rhtml” with @buyer passed in
as the local variable account
, then render
“advertiser/_ad.rhtml” and pass the local variable ad
to the
template for display.
Rendering a collection of partials
The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial by the same name as the elements contained within. So the three-lined example in “Using partials” can be rewritten with a single line:
<%= render :partial => "ad", :collection => @advertisements %>
This will render “advertiser/_ad.rhtml” and pass the local variable
ad
to the template for display. An iteration counter will
automatically be made available to the template with a name of the form
partial_name_counter
. In the case of the example above, the
template would be fed ad_counter
.
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.
Rendering shared partials
Two controllers can share a set of partials and render them like this:
<%= render :partial => "advertisement/ad", :locals => { :ad => @advertisement } %>
This will render the partial “advertisement/_ad.rhtml” regardless of which controller this is being called from.