开发者

Rails Helpers with iterators

开发者 https://www.devze.com 2023-03-29 00:27 出处:网络
I have the following helpe开发者_如何学运维r method: def tile_for( photo, tileClass = nil ) div_for( photo, :class => tileClass ) do

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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号