rico_mac
rico_mac

Reputation: 888

rails/ruby, passing multiple blocks as arguments

I have a rails helper method which I would like to pass two different blocks to be yielded in two different places in the method.

This is what I am trying to achieve in my view..

    <%= collapsible_content do %>
      <%= page_heading venue.title %>
      <%- venues_facility_opening_times venue %>
    <%-end %>

And this is the method itself

  def collapsible_content(&block1, &block2)
    content_tag(:div, nil, class: 'collapsible-content', data: { name: 'collapsible-1' }) do
      content_tag(:div, nil, class: 'collapsible-content-item') do
        concat button_tag(yield &block1, class: 'collapsible-content-toggle')
        concat hidden_content(&block2)
      end
    end
  end

  private

  def hidden_content(&block)
    content_tag(:div, class: "collapsible-content-body") do
      content_tag(:div, yield) if block_given?
    end
  end

However, from what i under stand the &block is always for the last argument, so how is it possible to differentiate between where they yield?

I tried using a lambda, but ActiveSupport::SafeBuffer prevents this.

Upvotes: 1

Views: 1373

Answers (1)

MrYoshiji
MrYoshiji

Reputation: 54882

Maybe this (2 Proc used)?

Definition:

def collapsible_content(proc1, proc2)
  content_tag(:div, some_options) do
    content_tag(:div, some_other_options) do
      concat button_tag(proc1.call)
      concat hidden_content(proc2.call)
    end
  end
end

def hidden_content(proc)
  content_tag(:div, class: "collapsible-content-body") do
    content_tag(:div, proc.call)
  end
end

Usage:

<%= collapsible_content(Proc.new{ page_heading(venue.title) }, Proc.new{ venues_facility_opening_times(venue) }) %>

Thanks to this post: Passing multiple code blocks as arguments in Ruby

Upvotes: 3

Related Questions