class Aggrobot::Aggregator

Public Class Methods

new(collection) click to toggle source
# File lib/aggrobot/aggregator.rb, line 6
def initialize(collection)
  @collection = collection
  @group_name_attribute, @count_attribute = :name, :count
  @group_labels_map = {}
  @attribute_mapping = {}
  self.collection(collection) if collection
end

Public Instance Methods

collection(values = nil) click to toggle source

returns collection if it is ActiveRecord::Relation or ActiveRecord::Base raises error when collection is none of the above returns @collection otherwise (which is nil)

# File lib/aggrobot/aggregator.rb, line 30
def collection(values = nil)
  if values
    if !values.is_a?(ActiveRecord::Relation) && values < ActiveRecord::Base
      values = values.unscoped
    end
    raise_error 'Collection should be an ActiveRecord::Relation or ActiveRecord::Base' unless values.is_a?(ActiveRecord::Relation)
    @collection = values
  else
    @collection
  end
end
group_by(group, opts = nil) click to toggle source

when

: opts is nil, groups by group on @collection
: opts is a map as {limit_to: limit}, creats groups by group on @collection with a limit
: opts is a map as {buckets: [list_items]}, creats groups by [list_items] on @collection
# File lib/aggrobot/aggregator.rb, line 46
def group_by(group, opts = nil)
  raise_error "Group_by takes only symbol or a string as argument" unless group.is_a?(Symbol) or group.is_a?(String)
  @query_planner = QueryPlanner.create(@collection, group, opts)
end
group_labels(map = nil, &block) click to toggle source

returns hash of group label(s) as key and actual column(s) as value

# File lib/aggrobot/aggregator.rb, line 15
def group_labels(map = nil, &block)
  if map || block
    if map.is_a?(Hash)
      @group_labels_map = ActiveSupport::HashWithIndifferentAccess.new(map)
    elsif map.respond_to?(:call) || block
      @group_labels_map = block || map
    end
  else
    @group_labels_map
  end
end
override(attr, override_attr = false) click to toggle source
# File lib/aggrobot/aggregator.rb, line 51
def override(attr, override_attr = false)
  case attr
    when :name
      @group_name_attribute = override_attr
    when :count
      @count_attribute = override_attr
    when Hash
      attr.each { |k, v| override(k, v) }
  end
end
query_planner() click to toggle source
# File lib/aggrobot/aggregator.rb, line 74
def query_planner
  @query_planner ||= QueryPlanner.create(@collection, DEFAULT_GROUP_BY)
end
select(name = nil, opts) click to toggle source

creates attribute map when:

given as hash, sets all keys as attributes to show and values as columns to fetch
given as list (of 2 items), first item is key to show and second item is column to fetch
# File lib/aggrobot/aggregator.rb, line 66
def select(name = nil, opts)
  if opts.is_a? Hash
    @attribute_mapping.merge!(opts)
  elsif name && opts
    @attribute_mapping[name] = opts
  end
end
yield_results() { |mapped_attributes(mapped_group_name, count, rest), mapped_group_name, relation| ... } click to toggle source
# File lib/aggrobot/aggregator.rb, line 78
def yield_results
  # yield on actual query results
  query_planner.query_results(extra_columns).each do |real_group_name, count, *rest|
    mapped_group_name = @group_labels_map[real_group_name] || real_group_name
    relation = @query_planner.sub_query(real_group_name)
    yield(mapped_attributes(mapped_group_name, count, rest), mapped_group_name, relation)
  end
end

Private Instance Methods

extra_attributes() click to toggle source
# File lib/aggrobot/aggregator.rb, line 93
def extra_attributes
  @attribute_mapping.keys
end
extra_columns() click to toggle source
# File lib/aggrobot/aggregator.rb, line 89
def extra_columns
  @attribute_mapping.map{|k, v| "#{v} as #{k}"}
end
mapped_attributes(group_name, count, result_row) click to toggle source
# File lib/aggrobot/aggregator.rb, line 97
def mapped_attributes(group_name, count, result_row)
  ActiveSupport::HashWithIndifferentAccess.new.tap do |attributes|
    attributes.merge!(Hash[extra_attributes.zip(result_row)]) unless result_row.empty?
    attributes[@count_attribute] = count if @count_attribute
    attributes[@group_name_attribute] = group_name if @group_name_attribute
  end
end