class TableCreator::ResultGroup

Attributes

group_object[RW]
level[RW]
rows[RW]
sum[RW]
total_levels[RW]

Public Class Methods

new(group_object, rows, total_levels = 0) click to toggle source
# File lib/table_creator/result_group.rb, line 7
def initialize(group_object, rows, total_levels = 0)
  @group_object = (group_object.blank? && group_object != false) ? nil : group_object.to_s
  @rows  = rows
  @level = 0
  @total_levels = total_levels
end

Public Instance Methods

aggregate(fields) click to toggle source

fields is a hash where:

key is the field/method
value is the aggregate type (currently only :sum)
# File lib/table_creator/result_group.rb, line 87
def aggregate(fields)
  invalid_aggregates = fields.values.uniq - [:sum]
  raise Error.new("Aggregation #{invalid_aggregates.to_sentence} not implemented") if invalid_aggregates.present?

  @sum ||= {}

  fields.each do |field, aggregation|
    @sum[field] = nil

    if @rows.first.is_a?(ResultGroup)
      @sum[field] = @rows.map do |row|
        # agregate each lower levels
        row.aggregate(fields)

        case aggregation
        when :sum
          row.sum[field]
        end
      end.compact.sum
    else
      @sum[field] = @rows.map do |row|
        case aggregation
        when :sum
          row.send(field) || 0 # encase result is nil
        end
      end.compact.sum
    end
  end
end
count() click to toggle source
# File lib/table_creator/result_group.rb, line 26
def count
  @rows.map { |r| r.is_a?(self.class) ? r.count : 1 }.sum
end
group(groups, order = nil) click to toggle source
# File lib/table_creator/result_group.rb, line 31
def group(groups, order = nil)
  groups = [groups] unless groups.is_a?(Array)

  return if groups.empty?
  new_rows = []

  first_group = groups.shift
  new_group = if @rows.first.is_a? ResultGroup
    @rows.map{|rg| [rg.group_object, rg.group_children(first_group, order)]}
  else
    if first_group == true
      {'All' => @rows}
    elsif first_group.is_a?(Hash)
      @rows.group_by{|r|
        r.send(first_group.keys.first).send(first_group.values.first)
      }
    else
      @rows.group_by{|r| r.send(first_group)}
    end
  end

  new_group = case order.try(:to_sym)
  when :group_name
    Hash[new_group.sort { |a,b| a.first.to_s <=> b.first.to_s }]
  when :row_count
    Hash[new_group.sort { |a,b| b.last.size <=> a.last.size }]
  else
    new_group
  end

  @total_levels += 1
  new_group.each do |group, rows|
    r = ResultGroup.new(group, rows, @total_levels)
    r.level = @level + 1
    new_rows << r
  end

  @rows = new_rows
  group(groups, order) unless groups.empty?
  @rows
end
group_children(group, order = nil) click to toggle source
# File lib/table_creator/result_group.rb, line 74
def group_children(group, order = nil)
  if @rows.first.is_a?(ResultGroup)
    @rows.each{|r| r.group_children(group, order)}
    @rows
  else
    self.group(group, order)
  end
end
level=(new_level) click to toggle source
# File lib/table_creator/result_group.rb, line 15
def level=(new_level)
  @level = new_level
  @rows.each do |row|
    if row.is_a? ResultGroup
      row.total_levels = @total_levels
      row.level = new_level + 1
    end
  end
end
to_data_rows(&block) click to toggle source
# File lib/table_creator/result_group.rb, line 118
def to_data_rows(&block)
  rows = []
  @rows.each do |row|
    if row.is_a? ResultGroup

      sub_rows = row.to_data_rows(&block)
      format = block.call(row, nil)

      if format.is_a? Hash
        group_data = format[:group]
        group_summary_data = format[:summary]
      elsif format.is_a? Array
        group_data = nil
        group_summary_data = format
      end

      if group_data.is_a? Array
        rows << {:class => "d#{@total_levels-row.level} l#{@total_levels} group", :data => group_data}
      elsif group_data.is_a? Hash
        rows << group_data.merge(:class => "h#{row.level}")
      end

      if group_summary_data.is_a? Array
        rows << {:class => "d#{@total_levels-row.level} l#{@total_levels} summary", :data => group_summary_data}
      elsif group_summary_data.is_a? Hash
        rows << group_summary_data.merge(:class => "h#{row.level}")
      end

      rows += sub_rows
    else
      format = block.call(nil, row)

      if format.is_a? Hash
        if format[:data].first.is_a? Array
          format[:data].each do |row|
            rows << row
          end
        else
          rows << format[:data]
        end
        
      elsif format.is_a? Array
        rows << format
      end
    end
  end
  rows
end