Pass a variable to a partial in Rails

Dynamic behavior from parent template to partial via parameter passing in Rails.

, updated

Rails partials are reusable view templates, but sometimes you need to pass data into them or handle optional variables. Here’s how to do it cleanly.

Passing Variables to a Partial

Use the locals option (or the shorthand hash syntax) to pass variables into a partial:

<%= render "shared/header", headline: "Welcome", person: person %>

Inside _header.html.erb, those locals are available as regular variables:

<h1><%= headline %></h1>
<p>First name: <%= person.first_name %></p>

Checking for Optional Variables

If a partial might or might not receive a variable, use local_assigns to check:

<% if local_assigns.has_key?(:headline) %>
  <h1><%= headline %></h1>
<% end %>

Don’t use defined? or !nil? — a local that’s explicitly passed as nil will still be “defined” but local_assigns.has_key? correctly distinguishes between “not passed” and “passed as nil”.

Rendering Conditionally Based on Locals

You can use local_assigns to dynamically choose which partial to render:

<%= render "discussions/complementary/#{local_assigns[:action] || params[:action]}" %>

This falls back to the current controller action if no action local is passed.

Default Values in Partials

Set defaults at the top of your partial using the || operator:

<% headline ||= "Default Headline" %>
<% subtitle ||= nil %>

<h1><%= headline %></h1>
<% if subtitle %>
  <h2><%= subtitle %></h2>
<% end %>

Collections with Locals

When rendering a collection, you can still pass additional locals:

<%= render partial: "shared/card", collection: @products, locals: { show_price: true } %>

Inside _card.html.erb:

<% if local_assigns[:show_price] %>
  <span class="price"><%= card.price %></span>
<% end %>

External Resources