views:

253

answers:

3

Are there any cases in which Rails overwrites controller instance variables on a render :partial call performed in a template? For example, let's say we have:

controller

def my_action
   @widget = Widget.find(params[:id])
end

view my_action.html.erb

Hi there.
<%= render :partial => 'my_helper' %>
That's it, that's all.

view _my_helper.html.erb

The id is <%= @widget.id.to_s %>.

Are there any documented scenarios (bugs or by design) in which @widget would be nil when used in my_helper? I'm seeing this behavior in an application and haven't been able to track down its source.

A few notes:
* The app is running in Rails 2.1.1.
* While it would be possible to assign locals to the render :partial => my_helper call, for a number of reasons locals aren't really ideal in this case.
* I spent a good chunk of time sifting through ActionController and ActionView, but haven't been able to isolate the behavior.

+1  A: 

Here's a somewhat lame suggestion: if practical, try using a different variable name.

Alternately, there's the old Pragmatic Programmer "tracer bullets" idea: create a dummy variable in the controller which you print out in various views/fragments, just to make sure that the scope/lifetime of these values really is what you expect, rather than "something" stomping on this one variable due to its unique name (or code you forgot you wrote).

Finally, you did try:

% find . -name '*rb*' | xargs grep -B 2 -A 2 -n '@widget'

or a similar code search in the application, right? Note that if you "freeze" your rails version, all of the rails framework code will be nested within you application, and you can search that, too.

Roboprog
A: 

Rails does not overwrite @widget.

BJ Clark
+1  A: 

No, Rails will not overwrite the instance variables in the partial.

Think of it like this: the view has access to all the instance variables of a controller and a partial is part of the view.

There can however, be use cases where a shared partial is used in views belonging to different controller. In that case, the code within the partial becomes confusing as you might not want to keep the name of the instance variables same within the methods of different controller. Using the locals hash is a better and cleaner option in such a case

Vaibhav Gumashta