ruby-on-railsruby-on-rails-3content-tag

rails extracting code from view to helper (content_tag misunderstanding?)


I got the following code in my view:

<ul class="thumbnails">
  <% Photo.find_all_by_id(my_params, limit: 10).each do |p| %>
    <li class="thumbnail">
      <%= image_tag(p.url(:fb)) %>
    </li>
  <% end %>
</ul>

It renders an unordered list with thumbnails. And it works okay - I see the list with images:

<ul class="thumbnails">
  <li class="thumbnail">
    <img alt="bmw" src="/assets/.../bmw.jpg?1364218949">
  </li>
</ul>

I would like to put it into helper, like this:

module PhotosHelper
  def photos_thumbs_by_ids(photos_ids)
    content_tag :ul, :class => "thumbnails" do
      Photo.find_all_by_id(photos_ids, limit: 10).each do |p|
        content_tag :li, :class => "thumbnail" do
          image_tag(p.url(:fb))
        end
      end
    end
  end
end

But when I use <%= photos_thumbs_by_ids my_params %> in my view, it renders only:

<ul class="thumbnails"></ul>

What am I doing wrong?


Solution

  • The problem is the each :

    Photo.find_all_by_id(photos_ids, limit: 10).each do |p|
    ...
    end
    

    It return an array, not the string. Try to collect it with 'map' and do a join

    module PhotosHelper
      def photos_thumbs_by_ids(photos_ids)
        content_tag :ul, :class => "thumbnails" do
          Photo.find_all_by_id(photos_ids, limit: 10).map { |p|
            content_tag :li, :class => "thumbnail" do
               image_tag(p.url(:fb))
            end
          }.join.html_safe
        end
      end
    end
    

    It's beacuse at least the rendering is done by the useful method capture. This method put in output buffer only if the result is a string, and don't try a to_s.