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 %>