Module: AggregateColumns::MethodsRails2

Defined in:
lib/aggregate_columns/methods_rails_2.rb

Instance Method Summary collapse

Instance Method Details

#aggregate_columns_options(*aggregates) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/aggregate_columns/methods_rails_2.rb', line 5

def aggregate_columns_options( *aggregates )
  all_joins = []
  all_selects = ["#{table_name}.*"]
  all_orders = []
  aggregates.each do |options|
    # Process options
    options.assert_valid_keys( :association, :column, :function, :result_column, :join_type, :conditions, :joins, :order )
    association = options[:association]
    unless association
      raise ArgumentError, "No association given" 
    end
    field = options[:column] || '*'
    function = options[:function] || :count
    result_column = options[:result_column]
    unless result_column
      # Defaults:
      # count(*) on comments => comment_count
      # sum(votes) on comment => comments_votes_sum
      result_column ||= field == '*' ? "#{association.to_s.singularize}_#{function}" : "#{association}_#{field}_#{function}"
    end
    assoc_reflection = reflect_on_association( association )
    foreign_key = assoc_reflection.primary_key_name # As stupid as it looks, this is actually correct
    table_name = assoc_reflection.table_name
    klass = assoc_reflection.klass
    join_type = options[:join_type] || "LEFT" # TODO: check if in range of allowed values
    order = options[:order] || "DESC"
    conditions = options[:conditions]
    joins = options[:joins]

    # Now gather params for aggregate
    all_joins << "#{join_type.to_s.upcase} JOIN (SELECT #{foreign_key}, #{function}(#{field}) AS #{result_column} FROM #{table_name} #{joins}#{" WHERE " + klass.sanitize_sql( conditions ) if conditions } GROUP BY #{foreign_key}) #{result_column}_join ON #{table_name}.id = #{result_column}_join.#{foreign_key}"
    all_selects << result_column.to_s
    all_orders << "#{result_column} #{order.to_s.upcase}"
  end
  return { :joins => all_joins.join( "\n" ), :select => all_selects.join( ', ' ), :order => all_orders.join( ', ' ) }
end

#aggregate_columns_scope(*aggregates) ⇒ Object



42
43
44
# File 'lib/aggregate_columns/methods_rails_2.rb', line 42

def aggregate_columns_scope( *aggregates )
  scoped( aggregate_columns_options( *aggregates ))
end