class ActionView::PartialRenderer

Experimental RBS support (using type sampling data from the type_fusion project).

# sig/action_view/renderer/partial_renderer.rbs

class ActionView::PartialRenderer < ActionView::AbstractRenderer
  def find_template: (String path, Array[] locals) -> ActionView::Template
  def render: (String partial, #<Class:0x0000000131b3f510> context, nil block) -> ActionView::AbstractRenderer::RenderedTemplate
end

As you can see, the :locals hash is shared between both the partial and its layout.
</div>
Title: <%= chief.name %>
Budget: $<%= user.budget %>
<div id=“administrator”>
…this will return:
<% end %>
Title: <%= chief.title %>
<%= render(layout: “administrator”, locals: { user: chief }) do %>
<%# app/views/users/_chief.html.erb %>
You can also apply a layout to a block within any template:
as available in the partial.
available as local variables inside the layout template under the same names
The current object being rendered, as well as the object_counter, will be
</ul>
</li>
Name: Bob
<li>
</li>
Name: Alice
<li>
<ul>
Given two users whose names are Alice and Bob, these snippets return:
</ul>
<%= render partial: “user”, layout: “li_layout”, collection: users %>
<ul>
<%# app/views/users/index.html.erb %>
</li>
<%= yield %>
<li>
<%# app/views/users/_li_layout.html.erb %>
</ul>
<% end -%>
</li>
<%= render partial: “user”, locals: { user: user } %>
<li>
<% users.each do |user| -%>
<ul>
<%# This does not use layouts %>
<%# app/views/users/index.html.erb %>
Name: <%= user.name %>
<%# app/views/users/_user.html.erb %>
the collection. For example, these two snippets have the same output:
If a collection is given, the layout will be rendered once for each item in
</div>
Name: <%= user.name %>
Deadline: <%= user.deadline %>
<div id=“editor”>
Here’s the editor:
</div>
Name: <%= user.name %>
Budget: $<%= user.budget %>
<div id=“administrator”>
Here’s the administrator:
…this will return:
</div>
<%= yield %>
Deadline: <%= user.deadline %>
<div id=“editor”>
<%# app/views/users/_editor.html.erb %>
</div>
<%= yield %>
Budget: $<%= user.budget %>
<div id=“administrator”>
<%# app/views/users/_administrator.html.erb %>
Name: <%= user.name %>
<%# app/views/users/_user.html.erb %>
<%= render partial: “user”, layout: “editor”, locals: { user: editor } %>
Here’s the editor:
<%= render partial: “user”, layout: “administrator”, locals: { user: administrator } %>
Here’s the administrator:
<%# app/views/users/index.html.erb %>
of users:
specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types
Partials can have their own layouts applied to them. These layouts are different than the ones that are
== Rendering partials with layouts
<%= render @posts %>
# <%= render partial: “posts/post”, collection: @posts %>
# that’s why we can replace:
# @posts is an array of Post instances, so every post record returns ‘posts/post’ on to_partial_path,
<%= render @account %>
# <%= render partial: “accounts/account”, locals: { account: @account} %>
# @account.to_partial_path returns ‘accounts/account’, so it can be used to replace:
<%= render “account”, account: @buyer %>
# Instead of <%= render partial: “account”, locals: { account: @buyer } %>
<%= render “account” %>
# Instead of <%= render partial: “account” %>
defaults of render to render partials. Examples:
If you’re not going to be using any of the options like collections or layouts, you can also use the short-hand
== Rendering the default case
<%= render partial: @posts %>
# <%= render partial: “posts/post”, collection: @posts %>
# that’s why we can replace:
# @posts is an array of Post instances, so every post record returns ‘posts/post’ on to_partial_path,
<%= render partial: @account %>
# <%= render partial: “accounts/account”, locals: { account: @account} %>
# @account.to_partial_path returns ‘accounts/account’, so it can be used to replace:
and pick the proper path by checking to_partial_path method.
Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work
== Rendering objects that respond to to_partial_path
This will render the partial advertisement/_ad.html.erb regardless of which controller this is being called from.
<%= render partial: “advertisement/ad”, locals: { ad: @advertisement } %>
Two controllers can share a set of partials and render them like this:
== Rendering shared partials
<%= render(partial: “ad”, collection: @advertisements) || “There’s no ad to be displayed” %>
to specify a text which will be displayed instead by using this form:
If the given :collection is nil or empty, render will return nil. This will allow you
<%= render partial: “ad”, collection: @advertisements, spacer_template: “ad_divider” %>
The following example will render advertiser/_ad_divider.html.erb between each ad partial:
You can specify a partial to be rendered between elements via the :spacer_template option.
The :as option may be used when rendering partials.
index method.
For backwards compatibility the partial_name_counter is still present and is mapped to the iteration’s
first? and last?. In the case of the example above, the template would be fed ad_iteration.
the collection and the total size of the collection. The iteration object also has two convenience methods,
partial_name_iteration. The iteration object has knowledge about which index the current object has in
iteration object will automatically be made available to the template with a name of the form
This will render advertiser/_ad.html.erb and pass the local variable ad to the template for display. An
<%= render partial: “ad”, collection: @advertisements %>
example in “Using partials” can be rewritten with a single line:
accepts an array and renders a partial by the same name as the elements contained within. So the three-lined
render a sub template for each of the elements. This pattern has been implemented as a single method that
The example of partial use describes a familiar pattern where a template needs to iterate over an array and
== Rendering a collection of partials
<%= render partial: “account”, locals: { user: @buyer } %>
This is equivalent to
<%= render partial: “account”, object: @buyer, as: ‘user’ %>
wanted it to be user instead of account we’d do:
With the :as option we can specify a different name for said local variable. For example, if we
<%= render partial: “account”, locals: { account: @buyer } %>
equivalent to:
would provide the @buyer object to the partial, available under the local variable account and is
<%= render partial: “account”, object: @buyer %>
The :object option can be used to pass an object to the partial. For instance:
By default ActionView::PartialRenderer doesn’t have any local variables.
== The :as and :object options
render advertiser/_ad.html.erb and pass the local variable ad to the template for display.
This would first render advertiser/_account.html.erb with @buyer passed in as the local variable account, then
<% end %>
<%= render partial: “ad”, locals: { ad: ad } %>
<% @advertisements.each do |ad| %>
<%= render partial: “account”, locals: { account: @buyer } %>
In another template for Advertiser#buy, we could have:
This would render “advertiser/_account.html.erb”.
<%= render partial: “account” %>
In a template for Advertiser#account:
templates that could be rendered on their own.
follow the naming convention of being prefixed with an underscore – as to separate them from regular
single object (we call this kind of sub templates for partials). It relies on the fact that partials should
There’s also a convenience method for rendering sub templates within the current controller that depends on a
= Action View Partials

def find_template(path, locals)

Experimental RBS support (using type sampling data from the type_fusion project).

def find_template: (String path,  locals) -> ActionView::Template

This signature was generated using 1 sample from 1 application.

def find_template(path, locals)
  prefixes = path.include?(?/) ? [] : @lookup_context.prefixes
  @lookup_context.find_template(path, prefixes, true, locals, @details)
end

def initialize(lookup_context, options)

def initialize(lookup_context, options)
  super(lookup_context)
  @options = options
  @locals  = @options[:locals] || {}
  @details = extract_details(@options)
end

def render(partial, context, block)

Experimental RBS support (using type sampling data from the type_fusion project).

def render: (String partial, #<Class:0x0000000131b3f510> context, nil block) -> ActionView::AbstractRenderer::RenderedTemplate

This signature was generated using 1 sample from 1 application.

def render(partial, context, block)
  template = find_template(partial, template_keys(partial))
  if !block && (layout = @options[:layout])
    layout = find_template(layout.to_s, template_keys(partial))
  end
  render_partial_template(context, @locals, template, layout, block)
end

def render_partial_template(view, locals, template, layout, block)

def render_partial_template(view, locals, template, layout, block)
  ActiveSupport::Notifications.instrument(
    "render_partial.action_view",
    identifier: template.identifier,
    layout: layout && layout.virtual_path,
    locals: locals
  ) do |payload|
    content = template.render(view, locals, add_to_stack: !block) do |*name|
      view._layout_for(*name, &block)
    end
    content = layout.render(view, locals) { content } if layout
    payload[:cache_hit] = view.view_renderer.cache_hits[template.virtual_path]
    build_rendered_template(content, template)
  end
end

def template_keys(_)

def template_keys(_)
  @locals.keys
end