views:

221

answers:

3

I have a helper method that creates navigation links for some controllers.

  def gen_associations(controllers)
    content_for :leftnav do
      sorted_controllers = controllers.sort
      returning String.new do |content|
        content << content_tag(:h3, "Associations") <<
        content_tag(:ul, :class => "nav") do
          sorted_controllers.collect do |c|
            content_tag("li", :class => ("last" if c == sorted_controllers.last)) do
              link_to(c.humanize, eval("admin_#{c}_url"))
            end
          end
        end
      end
    end
  end

I don't like this deeply nested structure, and the extra << and the end of one of the lines.

How can I rewrite it so it's not nested like that (in fewer lines) and without long lines (<80 chars)?

+6  A: 

use partial - put everything in returning closure there and then use render :partial => ...

tig
+3  A: 

Consider using something like markaby instead of content_tag; it makes your helpers far more readable. See also this railscast.

giorgian
+1  A: 

Build it from the inside-out:

  def gen_associations(controllers)
    sorted_controllers = controllers.sort

    list_items = 
      sorted_controllers.collect do |c|
        content_tag("li", :class => ("last" if c == sorted_controllers.last)) do
          link_to(c.humanize, eval("admin_#{c}_url"))
        end
      end

    list = content_tag(:ul, list_items.join, :class => "nav")

    content_for :leftnav do
      content_tag(:h3, "Associations") << list
    end
  end

I would probably move the content_for to the view or partial and just have gen_associations() return the list.

...
<% content_for :leftnav do %>
  <h3>Associations</h3>
  <%= gen_associations(@controllers) %>
<% end %>
...
Jerry Fernholz