Ruby On Rails : Partials : @instance variables unavailable in partials called from view

You might have experienced unavailability of instance variables inside a partial you call from a view template or a partial. Yes, you cannot access instance variable within a partial not rendered directly from a controller action.

Solution:

Using instance variable in partials works, but it can make it harder to maintain the app as changes are needed in the future.

The downside of using instance variables in partials is that you create a dependency in the partial to something outside the partial’s scope (coupling). This makes the partial harder to reuse, and can force changes in several parts of the application when you want to make a change in one part.

Partials that use instance variables:

  • must change when the instance variable in any controller that uses the partial changes either the instance variable name or its type or data structure
  • cause all controller actions that use the partial to change in the same way at the same time when there are changes to how the instance variable is used
  • discourage reuse, because they can only easily be reused in actions that set up instance variables with the same name and data

Instead, pass locals to the partials

<%= render 'reusable_partial', :item => @item %>

Now, because the partial only references item and not @item, the action that renders the view that renders the reusable_partial is free to change without affecting the reusable_partial and the other actions/views that render it:

<%= render 'reusable_partial', :item => @other_object.item %>

Also, this can be reused in contexts where there is no @item:

<%= render 'reusable_partial', :item => @duck %>

If my @duck changes in the future and no longer quacks like reusable_partial expects it to (the object’s interface changes), I can also use an adapter to pass in the kind of item that reusable_partial expects:

<%= render 'reusable_partial', :item => itemlike_duck(@duck) %>

Always?

There are plenty of situations where you probably don’t need de-coupled partials like this, and it’s easier in the short run to use an instance variable. However it’s hard to predict the future needs of your application, so this makes for a good general practice with relatively low cost.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s