Fix average on decimal and enum attributes

Follow up to #40351 and #41418.

This fixes `average` on decimal and enum (on integer in general)
attributes to not do `type.deserialize`.

The precision and the scale on the column might be lower than the
calculated result.

And also, mapping the calculated result to enum label is quite
meaningless, the mapping result is almost nil.
This commit is contained in:
Ryuta Kamizono 2021-02-13 14:18:57 +09:00
parent 8dc7439058
commit e450a4a497
2 changed files with 20 additions and 7 deletions

@ -449,7 +449,12 @@ def type_cast_calculated_value(value, operation, type)
when "sum"
type.deserialize(value || 0)
when "average"
type.is_a?(Type::Integer) ? value&.to_d : type.deserialize(value)
case type.type
when :integer, :decimal
value&.to_d
else
type.deserialize(value)
end
else # "minimum", "maximum"
type.deserialize(value)
end

@ -55,10 +55,10 @@ def test_should_return_decimal_average_of_integer_field
end
def test_should_return_integer_average_if_db_returns_such
ShipPart.delete_all
ShipPart.create!(id: 3, name: "foo")
value = ShipPart.average(:id)
assert_equal 3, value
value = Book.average(:status)
assert_equal 1.0, value
assert_instance_of BigDecimal, value
end
def test_should_return_float_average_if_db_returns_such
@ -67,13 +67,21 @@ def test_should_return_float_average_if_db_returns_such
assert_equal 37.5, value
assert_instance_of Float, value
if current_adapter?(:PostgreSQLAdapter, :SQLite3Adapter)
NumericData.create!(temperature: "Infinity")
value = NumericData.average(:temperature)
assert_equal Float::INFINITY, value
assert_instance_of Float, value
end
end
def test_should_return_decimal_average_if_db_returns_such
NumericData.create!(bank_balance: 37.50)
NumericData.create!([{ bank_balance: 37.50 }, { bank_balance: 37.45 }])
value = NumericData.average(:bank_balance)
assert_equal 37.50, value
assert_equal 37.475, value
assert_instance_of BigDecimal, value
end