How to create an assistant with a block?

I want to make an assistant as follows.

def my_div some_options, & block
  # How do I print the result of the block?
end
+7
source share
3 answers

You must use CaptureHelper .

def my_div(some_options, &block)
  # capture the value of the block a string
  content = capture(&block)
  # concat the value to the output
  concat(content)
end

<% my_div([]) do %>
  <p>The content</p>
<% end %>


def my_div(some_options, &block)
  # capture the value of the block a string
  # and returns it. You MUST use <%= in your view.
  capture(&block)
end

<%= my_div([]) do %>
  <p>The content</p>
<% end %>

Use capture + concat if you need to execute output. Use capture if you need to capture and then reuse content. If your block does not explicitly use <% =, then you MUST call concat (preferred method).

This is an example of a method that hides content if the user is not an administrator.

def if_admin(options = {}, &block)
  if admin?
    concat content_tag(:div, capture(&block), options)
  end
end

<% if_admin(:style => "admin") do %>
<p>Super secret content.</p>
<% end %>
+15
source

http://www.rubycentral.com/book/tut_containers.html

yield . , (?)

def my_div &block
  yield
end

my_div { puts "Something" } 

"-"

: ? DIV?

+1

So, two things that are important:

  • rails ignores everything that is not a string in content_tag(and content_for)
  • you cannot use Array#join(etc.) because it creates unsafe lines, you need to use safe_joinand content_tagto have safe lines
  • I did not need captureeither concatin my case.
  def map_join(objects, &block)
    safe_join(objects.map(&block))
  end

  def list(objects, &block)
    if objects.none?
      content_tag(:p, "none")
    else
      content_tag(:ul, class: "disc") do
        map_join(objects) do |object|
          content_tag(:li) do
            block.call(object)
          end
        end
      end
    end
  end

this can be used like this:

= list(@users) do |user|
  => render user
  = link_to "show", user 

(this is subtle, but works fine with erb too)

0
source

All Articles