Module: CompositePrimaryKeys::ActiveRecord::Calculations
- Included in:
- CompositeRelation
- Defined in:
- lib/composite_primary_keys/relation/calculations.rb
Instance Method Summary collapse
- #aggregate_column(column_name) ⇒ Object
- #build_count_subquery(relation, column_name, distinct) ⇒ Object
- #calculate(operation, column_name) ⇒ Object
-
#execute_simple_calculation(operation, column_name, distinct) ⇒ Object
:nodoc:.
Instance Method Details
#aggregate_column(column_name) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/composite_primary_keys/relation/calculations.rb', line 4 def aggregate_column(column_name) # CPK if column_name.kind_of?(Array) # Note: Test don't seem to run this code? column_name.map do |column| @klass.arel_table[column] end elsif @klass.has_attribute?(column_name) || @klass.attribute_alias?(column_name) @klass.arel_table[column_name] else Arel.sql(column_name == :all ? "*" : column_name.to_s) end end |
#build_count_subquery(relation, column_name, distinct) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/composite_primary_keys/relation/calculations.rb', line 60 def build_count_subquery(relation, column_name, distinct) if column_name == :all column_alias = Arel.star # CPK # relation.select_values = [ Arel.sql(FinderMethods::ONE_AS_ONE) ] unless distinct relation.select_values = [ Arel.sql(::ActiveRecord::FinderMethods::ONE_AS_ONE) ] unless distinct elsif column_name.is_a?(Array) column_alias = Arel.star relation.select_values = column_name.map do |column| Arel::Attribute.new(@klass.unscoped.table, column) end else column_alias = Arel.sql("count_column") relation.select_values = [ aggregate_column(column_name).as(column_alias) ] end subquery_alias = Arel.sql("subquery_for_count") select_value = operation_over_aggregate_column(column_alias, "count", false) relation.build_subquery(subquery_alias, select_value) end |
#calculate(operation, column_name) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/composite_primary_keys/relation/calculations.rb', line 82 def calculate(operation, column_name) if has_include?(column_name) relation = apply_join_dependency if operation.to_s.downcase == "count" unless distinct_value || distinct_select?(column_name || select_for_count) relation.distinct! # CPK # relation.select_values = [ klass.primary_key || table[Arel.star] ] if klass.primary_key.present? && klass.primary_key.is_a?(Array) relation.select_values = klass.primary_key.map do |k| "#{connection.quote_table_name(klass.table_name)}.#{connection.quote_column_name(k)}" end else relation.select_values = [ klass.primary_key || table[Arel.star] ] end end # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT relation.order_values = [] if group_values.empty? end relation.calculate(operation, column_name) else perform_calculation(operation, column_name) end end |
#execute_simple_calculation(operation, column_name, distinct) ⇒ Object
:nodoc:
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/composite_primary_keys/relation/calculations.rb', line 18 def execute_simple_calculation(operation, column_name, distinct) #:nodoc: column_alias = column_name # CPK # if operation == "count" && (column_name == :all && distinct || has_limit_or_offset?) # # Shortcut when limit is zero. # return 0 if limit_value == 0 # # query_builder = build_count_subquery(spawn, column_name, distinct) if operation == "count" relation = unscope(:order) query_builder = build_count_subquery(spawn, column_name, distinct) else # PostgreSQL doesn't like ORDER BY when there are no GROUP BY relation = unscope(:order).distinct!(false) column = aggregate_column(column_name) select_value = operation_over_aggregate_column(column, operation, distinct) select_value.distinct = true if operation == "sum" && distinct relation.select_values = [select_value] query_builder = relation.arel end result = skip_query_cache_if_necessary { @klass.connection.select_all(query_builder) } if operation != "count" type = column.try(:type_caster) || lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value type = type.subtype if ::ActiveRecord::Enum::EnumType === type end type_cast_calculated_value(result.cast_values.first, operation, type) do |value| type = column.try(:type_caster) || # CPK # lookup_cast_type_from_join_dependencies(column_name.to_s) || Type.default_value lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value type.deserialize(value) end end |