Class: Aggrobot::Aggregator

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/aggrobot/aggregator.rb

Instance Method Summary collapse

Methods included from Helper

#block_from_args, #raise_error

Constructor Details

#initialize(collection) ⇒ Aggregator

Returns a new instance of Aggregator.



6
7
8
9
10
11
12
# 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

Instance Method Details

#collection(values = nil) ⇒ Object

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)



30
31
32
33
34
35
36
37
38
39
40
# 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) ⇒ Object

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


46
47
48
49
# 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) ⇒ Object

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



15
16
17
18
19
20
21
22
23
24
25
# 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) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# 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_plannerObject



74
75
76
# File 'lib/aggrobot/aggregator.rb', line 74

def query_planner
  @query_planner ||= QueryPlanner.create(@collection, DEFAULT_GROUP_BY)
end

#select(name = nil, opts) ⇒ Object

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


66
67
68
69
70
71
72
# 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_resultsObject



78
79
80
81
82
83
84
85
# 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