Nithin Bekal

Posts About Notes Slides

Passing optional locals to Rails partials

16 Feb 2015

When passing locals to Rails partials, you might run into cases where you need to pass optional locals in some places, but don’t want to pass it in every other place where you use the partial.

As an example, you have a _post partial which you render like this:

<%= render 'post', post: post %>

And now you want to render the same partial from another view, but this time you want to pass a boolean flag to tell the partial to render the author bio as well.

<%= render 'post', post: post, show_author_bio: true %>

If we now used the show_author_bio local in the partial, it would break the other view which does not know about this local. To use it safely, we can make use of the local_assigns hash.

<h1><%= post.title %></h1>

<% if local_assigns[:show_author_bio] %>
  <%= render 'author_bio', author: post.author %>
<% end %>

<%= post.body %>

Even though we’re using it for passing a boolean value here, we could pass in any other object as well. For instance, we could pass in an optional author object:

<% if local_assigns.has_key?(:author) %>
  <%= render 'author_bio', author: author %>
<% end %>

Sadly, Rails documentation seems to be missing details about this useful feature. I'm not sure if this is because it has been deprecated since Rails 4. Do leave a comment below if you know why.

Update: In earlier versions of Rails, using defined? did no work reliably in the views. This is not the case in 4.2, so the part of the ActionView::Base docs that mentioned defined? and local_assigns was removed. You can use defined? like this:

<% if defined?(:author) %>
  <%= render 'author_bio', author: author %>
<% end %>

local_assigns is still available though, and is still useful in cases where you need to access the locals as a hash.

Update 2: I went ahead and submitted a pull request adding documentation for local_assigns. There’s also another open issue for the same (#15700) that also added documentation. Hopefully we will soon have documentation for local_assigns.

DHH also opened an issue (#18962) about this yesterday, and had an interesting comment to make about this feature. ;-)

These f***ing Rails people have thought of everything! local_assigns is exactly this and already available.

Links

Hi, I’m Nithin Bekal. I work at Shopify in Ottawa, Canada. Previously, co-founder of CrowdStudio.in and WowMakers. Ruby is my preferred programming language, and the topic of most of my articles here, but I'm also a big fan of Elixir. Tweet to me at @nithinbekal.