Search code examples
ruby-on-railsrubyblockview-helpers

Ruby: Pass default parameter to a method when it is called inside a block


I try to create a very simple Rails helper to generate me a fancybox image preview. It should produce the following HTML:

<a href="path-to-image" class="fancybox">
  <img src="path-to-image-thumb" ... />
</a>

However, to output a clickable gallery of many images, I need to set the rel attribute to the same value for all of the links:

<a href="path-to-image" class="fancybox" rel="my-gallery">
  <img src="path-to-image-thumb" ... />
</a>
<a href="path-to-image2" class="fancybox" rel="my-gallery">
  <img src="path-to-image2-thumb" ... />
</a>

I'd like to do this like the following:

# Single image
<%= image_preview(image) %>

# Image gallery
<%= image_gallery('my-gallery') do |g| %>
  <%= g.image_preview(image) %>
  <%= g.image_preview(image2) %>
<% end %>

So I want to use the same image_preview method both in a block and without one, but I'm struggling with the implementation.

My current implementation (which doesn't work) looks like this:

def image_preview(image, options = {})
  link_to image.url, class: 'fancybox' do # How do I decide whether I have to put the rel attribute?
    image_tag image.url(:thumb), options
  end
end

def image_gallery(name, &block)
  yield self # Somehow I have to use the provided name as rel attribute in image_preview...
end

I also tried my luck with with_options but didn't really get it to work for me (and sincerely don't exactly know how to use it for this case).


Solution

  • My implementation looks like this:

    module ImageGalleryHelper
      def image_gallery(name = nil, &block)
        name ||= 'gallery_' + SecureRandom.hex(6)
    
        content_tag :div, class: name do
          with_options gallery_name: name do |gallery|
            yield gallery
          end
        end
      end
    
      def fancy_image(image, options = {})
        content_tag :a, href: image.url, class: 'fancybox', rel: options.delete(:gallery_name) do
          image_tag image.url(:thumb), options
        end
      end
    end
    

    This does exactly what I want it to do. Maybe there are some enhancements possible?