Blocks in views

This is more of an academic question, but I was wondering why the
following doesn’t work in a view:

<%= @items.each { |@item| render :partial => ‘itemrow’ } %>

Of course it can be done like this, which works:

<% for @item in @items %>
<%= render :partial => ‘itemrow’ %>
<% end %>

But I was curious as to why the first method doesn’t work (at least it
doesn’t work for me). Is it not possible to use blocks in views?

Hi, it should be

| item | instead of | @item |

Also, I would recommend reading the section of AWDWR on using partials
to render collections.

Peace,

-Conrad

Hi –

On Sat, 18 Nov 2006, zerohalo wrote:

<% end %>

But I was curious as to why the first method doesn’t work (at least it
doesn’t work for me). Is it not possible to use blocks in views?

What’s happening is this:

<%= … %> interpolates the string representation of whatever “…”
evaluates to. In this case, “…” is a call to @items.each. The each
method returns its receiver. So, in effect, what you’re doing is:

<%= @items.to_s %>

If you do the “for @item” one, or this:

<% @items each do |@item| %>
<%= render :partial => “itemrow” %>
<% end %>

then you’re interpolating the string representation of the rendering
of the partial, zero or more times in succession. You could also do:

<%= @items.map {|@item| render :partial => “itemrow” } %>

which would give you an array of all the rendered results. It’s a
little less straightforward, though, and depends on representing an
array as a string, which is an unnecessary extra step. Mainly I
mention it to illustrate the principle at work, which the difference
between each and map shows you.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

What do you mean by “doesn’t work”? Error? No output? Only one line of
output?

In any case, what <%= %> does is evaluate the Ruby inside it and
concatenate
the results onto the erb stream. The block you have specified returns, I
believe, not a concatenation of the partials, but rather the last
partial
evaluated.

HTH

Daan P. wrote:

<%= render :partial => ‘itemrow’ %>
<% end %>

But I was curious as to why the first method doesn’t work (at least it
doesn’t work for me). Is it not possible to use blocks in views?


View this message in context:
http://www.nabble.com/-Rails--blocks-in-views-tf2661201.html#a7422902
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Hi –

On Sat, 18 Nov 2006, Conrad T. wrote:

| item | instead of | @item |
Actually you can use instance variables as block params. Try this in
irb:

[1,2,3].each {|@x| p @x }

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

You can – the syntax is parseable – but that’s not usually what you
meant. If you needed an instance variable for a method call, I guess
this
would make sense, but it still seems strange and an unintentional use of
legal syntax.

dblack wrote:

Actually you can use instance variables as block params. Try this in
irb:

[1,2,3].each {|@x| p @x }


View this message in context:
http://www.nabble.com/-Rails--blocks-in-views-tf2661201.html#a7423050
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Hi –

On Sat, 18 Nov 2006, s.ross wrote:

would make sense, but it still seems strange and an unintentional use of
legal syntax.

I’ve done it sometimes when I want to do something like:

<% @items.each do |@item| %>
<%= text_field “item[]”, “name” %>
<% end %>

It could also come in handy with rendering a partial, as it could save
you the trouble of doing a :locals thing.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Thanks, David, for the explanation. I didn’t understand the difference
between map and each.

And you’re exactly right, the wrong output that I got with the block
was simply the array @items – the partial itself wasn’t output even
once.

Hi –

On Sat, 18 Nov 2006, s.ross wrote:

<% for @item in @items %>
<%= render :partial => ‘itemrow’ %>
<% end %>

But I was curious as to why the first method doesn’t work (at least it
doesn’t work for me). Is it not possible to use blocks in views?

What do you mean by “doesn’t work”? Error? No output? Only one line of
output?

I think the output will be a single hash-mark for each item in @items,
representing a shortened string representation.

In any case, what <%= %> does is evaluate the Ruby inside it and concatenate
the results onto the erb stream. The block you have specified returns, I
believe, not a concatenation of the partials, but rather the last partial
evaluated.

Actually it returns the original array, @items. The results of the
calls to render are discarded.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org