Partial loop counter override by local variable

The following is an issue I raised over in the Rails Talk group and it was suggested that I bring it up here...

Although not documented as far as I'm aware, prior to Rails 2.1 it was possible to pass a local variable to a partial with the same name as the partial's internal collection counter variable, i.e. <name>_counter, and have it take on the value that is passed. I have found this to be extremely useful in situations where I have a collection of items to be rendered, but also want to be able to add an item to the page one at a time after it has initially been rendered, in response to an ajax request, e.g. so I can allow the user to add new fields to a form.

In a situation like this the ordinality of the new item relative to the others may be important to how it is rendered, but of course the internal counter disappears once the initial collection has been rendered. What I had been doing here was to have an rjs template invoke the same partial used for the collection but on an object, and pass the counter in as a local to ensure that the object gets treated the right way with respect to the items already rendered.

Unfortunately, the ability to do this appears to have disappeared in 2.1, and leaves me resorting to some pretty nasty stuff to achieve the same effect. It appears that regardless of the value passed to the local variable, when the partial is invoked on an object, internally the variable is just set to zero.

This seems like a step backwards. Anyone want to explain the thinking behind this, or suggest an elegant alternative strategy for implementing the kind of case I described?

Unfortunately, the ability to do this appears to have disappeared in 2.1, and leaves me resorting to some pretty nasty stuff to achieve the same effect. It appears that regardless of the value passed to the local variable, when the partial is invoked on an object, internally the variable is just set to zero.

Looks like it's back in edge :slight_smile: Assuming it's desirable behaviour, sounds to me like the right thing
to do would be to add a test for it so that it doesn't get trampled on
in the future.

Fred

Just ran into the same issue as MarkMT. The code required for the functionality he describes is fairly nasty atm.

Glad to hear the original way is back in Edge, just need the next official release now!

Just ran into the same issue as MarkMT. The code required for the functionality he describes is fairly nasty atm.

Glad to hear the original way is back in Edge, just need the next official release now!

Do you have a test for this? We can merge it to 2.1 before we put out 2.1.1 (hopefully soon).

I've just tried the following on Edge;

<%= render(:partial => 'example', :collection => %w(rails-doc is cool), :locals => {:example_counter => 5}) %>

in the 'example' partial;

<p>Element: <%= example %> (index: <%= example_counter %>)</p>

output;

Element: rails-doc (index: 0) Element: is (index: 1) Element: cool (index: 2)

so not only has the behaviour changed (counter starting from 0, not 1), it's still not allowing it to be overridden.

How did you check it was working, Frederick?

@Koz - I'll try and write a patch/test which allows the internal counter to be overridden.

My bad, it does work.

<%= render(:partial => 'example', :locals => {:example_counter => 5}) %>

Which is how you'd call it from an AJAX request, works.

I'll look into whether there's a test case.

Hi Koz, added a patch for the tests to Lighthouse.

http://rails.lighthouseapp.com/projects/8994/tickets/766

Cam