Fork me on GitHub
Hoopla! - now with extra whiz-bang home

It turns out that the syntax used in fields_for to allow a block embedded in ERB is remarkably simple. I ripped the guts out of form_for and used it's basic block logic to power my own helper that I called, simply 'section'. First, here's the view now that I can use a block:

  <%  section 'Strength' do %>
    <%= data :forty_time, 'Forty time' %>
    <%= data :bench_press, 'Bench Press (Max)' %>
    <%= data :squat_max, 'Squat (Max)' %>
    <%= data :clean_max, 'Clean (Max)' %>
  <%  end %>
Way, way, way cleaner. The best part about this is that it's actually semantic. I'm specifying that I want to start a block named 'Strength' and I'm going to put an arbitrary number of elements into it. Am I going to use an unordered list? Doesn't matter! I can leave that to the helper and keep a single point of code maintenance. So let's take a look at the super-complicated (as Ruby always is) method that allows this. Here's my updated helper:
module AthletesHelper
  def section(name, &proc)
    raise ArgumentError, "Missing block" unless block_given?
    concat('
    ', proc.binding) concat(content_tag(:h2, name), proc.binding) yield # this is where the stuff in the block get's eval'd and inserted concat('
', proc.binding) end def data(att, label) content_tag(:li, content_tag(:label, label)+ content_tag(:div, @athlete_contact.send(att), :id => "contact_#{att.to_s}", :class => 'data')) end end
It's that simple. You may find the part about concat('text', proc.binding) a little confusing - I certainly did. I won't try to pretend I completely graps it except to say that when *concat* is passed proc.binding it executes the code in the environment of the proc. In other words,
concat('
    ', proc.binding)
is the same as having typed
<%= '
    ' %>
blog comments powered by Disqus