Rails Helpers with iterators
I have the following helpe开发者_如何学运维r method:
def tile_for( photo, tileClass = nil )
div_for( photo, :class => tileClass ) do
link_to( image_tag( photo.image_url(:sixth) ), photo )
content_tag( :div, photo.location(:min), :class => 'caption' )
end
end
The problem is, it returns this kind of output:
<div id="photo_25" class="photo">
<div class="caption" style="display: none;">Berlin</div>
</div>
As you can see the link_to
is not being output. I guess this is because only the returned value of the block is being included, rather than each executed line? I don't really understand why this kind of code works perfectly in views but doesn't work the same at all in helper methods. Can anyone enlighten me on what's going on and why it works the way it works? How would you build an loop helper method like this?
It works in views since ERB is really just a big concatenation engine. You need to "manually" do this work in your helper, since the code will not be interpreted by ERB:
def tile_for( photo, tileClass = nil )
div_for( photo, :class => tileClass ) do
link_to(image_tag( photo.image_url(:sixth)), photo)
+ # <- Add this so the block returns the whole string
content_tag(:div, photo.location(:min), :class => 'caption')
end
end
div_for
also supports arrays, which will be collected into one continuous string. So you can also do like so:
[link_to(image_tag(photo.image_url(:sixth)), photo),
content_tag(:div, photo.location(:min), :class => 'caption')]
Any of the other answers would do. Now, an explanation on why it does works in ERB.
In an ERB template, when a <%= is found, it gets translated to "#{@insert_cmd}((#{content}).to_s)"
. A simple example: <%= "a" %>
gets translated to print "a"
.
You can take a look at line 631 in erb.rb but skim the previous code for a shake of context (related to the content).
Only the last value of a block is returned. You'll need to make sure your block returns a single value:
def tile_for( photo, tileClass = nil )
div_for( photo, :class => tileClass ) do
link_to( image_tag( photo.image_url(:sixth) ), photo ) +
content_tag( :div, photo.location(:min), :class => 'caption' )
end
end
精彩评论