Module: CompositePrimaryKeys::ActiveRecord::Calculations

Included in:
CompositeRelation
Defined in:
lib/composite_primary_keys/relation/calculations.rb

Instance Method Summary collapse

Instance Method Details

#aggregate_column(column_name) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/composite_primary_keys/relation/calculations.rb', line 4

def aggregate_column(column_name)
  # CPK
  if column_name.kind_of?(Array)
    column_name.map do |column|
      Arel::Attribute.new(@klass.unscoped.table, column)
    end
  elsif @klass.column_names.include?(column_name.to_s)
    Arel::Attribute.new(@klass.unscoped.table, column_name)
  else
    Arel.sql(column_name == :all ? "*" : column_name.to_s)
  end
end

#build_count_subquery(relation, column_name, distinct) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/composite_primary_keys/relation/calculations.rb', line 41

def build_count_subquery(relation, column_name, distinct)
  return super(relation, column_name, distinct) unless column_name.kind_of?(Array)
  # CPK
  # column_alias = Arel.sql('count_column')
  subquery_alias = Arel.sql('subquery_for_count')

  # CPK
  # aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias)
  # relation.select_values = [aliased_column]
  relation.select_values = column_name.map do |column|
    Arel::Attribute.new(@klass.unscoped.table, column)
  end

  relation = relation.distinct(true)
  subquery = relation.arel.as(subquery_alias)

  sm = Arel::SelectManager.new relation.engine
  # CPK
  # select_value = operation_over_aggregate_column(column_alias, 'count', distinct)
  select_value = operation_over_aggregate_column(Arel.sql("*"), 'count', false)
  sm.project(select_value).from(subquery)
end

#execute_simple_calculation(operation, column_name, distinct) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/composite_primary_keys/relation/calculations.rb', line 17

def execute_simple_calculation(operation, column_name, distinct)
  # Postgresql doesn't like ORDER BY when there are no GROUP BY
  relation = reorder(nil)

  # CPK
  #if operation == "count" && (relation.limit_value || relation.offset_value)
  if operation == "count"
    # Shortcut when limit is zero.
    return 0 if relation.limit_value == 0

    query_builder = build_count_subquery(relation, column_name, distinct)
  else
    column = aggregate_column(column_name)

    select_value = operation_over_aggregate_column(column, operation, distinct)

    relation.select_values = [select_value]

    query_builder = relation.arel
  end

  type_cast_calculated_value(@klass.connection.select_value(query_builder.to_sql), column_for(column_name), operation)
end