[LRUG] Funny gotcha with blocks in partials.

Andrew Stewart boss at airbladesoftware.com
Mon Jun 22 09:16:45 PDT 2009


On 22 Jun 2009, at 16:31, Tim Cowlishaw wrote:
> So, this works exactly as expected when i pass it a pure ruby block  
> argument:
>
> <%= array_to_list(@flash_games, :class => "flash_games_grid") do | 
> game, array|
>        link_to(game_path(:id => game.id,  
> image_tag(game.image_url(:grid), :alt => 'A Game'. :width =>  
> 128, :height => 128))
> %>
>
> However, if i pass it a block that contains ERB template strings, it  
> breaks - it just returns the result of each call to the block direct  
> to the template being rendered, as it's executed, rather than  
> returning it as the result of the call to array_to_list itself:
>
> <% array_to_list(@flash_games, :class => "flash_games_grid") do | 
> game, array| %>
>        <a href="<%= game_path(:id => game.id) %>"><img src="<%=  
> game.image_url(:grid) %>" alt="A Game" width="128" height="128" /></a>
> <% end %>
>
> I have a suspicion that this is something the rails capture() method  
> might be needed for, but i'm struggling to understand how, Anyone  
> seen anything similar in the past?

I run into this sort of thing every now and again, and each time the  
solution is slightly different because Rails has changed its  
implementation.  As I understand it, all ERB evaluation goes directly  
to the output buffer for the template being rendered -- as you found.   
If you want to evaluate some ERB, but without the output going  
directly to the buffer, you need capture.

capture() simply sends to a temporary buffer the result of executing  
its block, outputs the temporary buffer once the block has been  
executed, then carries on as before.

http://github.com/rails/rails/blob/ecc054352512cac8c0895c78c5f3d043046dcfec/actionpack/lib/action_view/helpers/capture_helper.rb#L127

So I imagine (though haven't tested) this would work:

<% capture do %>
   <% array_to_list(@flash_games, :class => "flash_games_grid") do | 
game, array| %>
     <a href="<%= game_path(:id => game.id) %>"><img src="<%=  
game.image_url(:grid) %>" alt="A Game" width="128" height="128" /></a>
   <% end %>
<% end %>

The other helper with pops up in this kind of problem is concat(string).

Cheers,
Andy Stewart



More information about the Chat mailing list