class GroupHierarchy
  def initialize(root)
    @root = root
  end

  def to_hash
    export(@root)
  end

private

  def export(group)
    {
      name: group.name,
      url: Rails.application.routes.url_helpers.group_path(group),
      children: group.children.map { |g| export(g) }
    }
  end
end

class GroupHierarchy
  FIELDS = [:id, :name, :slug, :parent_id]
  LiteGroup = Struct.new(*FIELDS)

  def initialize(root)
    @root = root
  end

  def to_hash
    export(@root)
  end

private

  def export(group)
    {
      name: group.name,
      url: group_path(group),
      children: children(group).map { |g| export(g) }
    }
  end

  def children(group)
    lookup.select { |g| g.parent_id == group.id }.sort_by(&:name)
  end

  def group_path(lg)
    Rails.application.routes.url_helpers.group_path(id: lg.slug)
  end

  def lookup
    @lookup ||= Group.pluck(*FIELDS).map { |a| LiteGroup.new(*a) }
  end
end

Make group hierarchy generation efficient
Make group hierarchy generation efficient

It now uses one query instead of one for every group in the database.
