Nested Helper Classes vs Private Helper Methods
While criticism towards Rails helpers has almost become folklore (procedural, global scope, junk drawers), I still find myself reaching for them as a low ceremony way of making templates more concise and building simple view layer APIs.
Obviously, the greatest downside of helper modules is how dangerous extracting private methods becomes.
module UsersHelper
  def user_section(user)
    content_tag(:section, user.name, class: css_class(user))
  end
  private
  def css_class(user)
    ['user', user.role].join(' ')
  end
end
module PostsHelper
  def post_section
    content_tag(:section, post.text, class: css_class(post))
  end
  private
  # collides with UsersHelper#css_class
  def css_class(post)
    'post'
  end
end
While I always liked extracting classes to keep helper methods short, only recently did I realize how a nuance in Ruby's constant look-up mechanism helps prevent namespace collisions as above.
Let's look at a variant of the above helpers that uses nested classes instead of private methods.
module UsersHelper
  def user_section(user)
    Section.new(user).render(self)
  end
  class Section < Struct.new(:user)
    def render(template)
      template.content_tag(:section, user.name, class: css_class)
    end
    private
    def css_class
      ['user', user.role].join(' ')
    end
  end
end
module PostsHelper
  def post_section(post)
    Section.new(post).render(self)
  end
  class Section < Struct.new(:post)
    def render(template)
      template.content_tag(:section, post.text, class: css_class)
    end
    private
    def css_class
      'post'
    end
  end
end
At first glance, one could expect the same problem as above. Instead of both defining an equally named private method, both modules now contain a nested class with the same name. Once both modules get included into the view object only one can win, right? That's sure the way it looks when we try to reference one of the nested classes from a template:
  # app/views/users/index.html.erb
  <%= Section == PostsHelper::Section # => true %>
But in contrast to method invocations, which are resolved by the
object handling the call, constant look-up uses the lexical scope at
the point where the constant is referenced. So referring to a
Section class inside UsersHelper still resolves to
UsersHelper::Section, no matter whether there is a colliding
PostsHelper::Section class when including helper modules into the
view context.
Nested helper classes thus provide a safe space for refactoring towards small methods. Helper methods end up containing only wiring code, keeping implementation details from leaking into tests or templates.