1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Allow Relation#sum to take an init parameters

This is needed to not prevent full use of `Enumerable#sum`
on `Relation` objects.
This commit is contained in:
Jean Boussier 2021-05-10 11:05:02 +02:00
parent 2af458a10d
commit e672575906
2 changed files with 22 additions and 11 deletions

View file

@ -83,15 +83,24 @@ module ActiveRecord
# #calculate for examples with options. # #calculate for examples with options.
# #
# Person.sum(:age) # => 4562 # Person.sum(:age) # => 4562
def sum(column_name = nil) def sum(identity_or_column = nil, &block)
if block_given? if block_given?
unless column_name.nil? values = map(&block)
raise ArgumentError, "Column name argument is not supported when a block is passed." if identity_or_column.nil? && (values.first.is_a?(Numeric) || values.first(1) == [])
identity_or_column = 0
end end
super() if identity_or_column.nil?
ActiveSupport::Deprecation.warn(<<-MSG.squish)
Rails 7.0 has deprecated Enumerable.sum in favor of Ruby's native implementation available since 2.4.
Sum of non-numeric elements requires an initial argument.
MSG
values.inject(:+) || 0
else else
calculate(:sum, column_name) values.sum(identity_or_column)
end
else
calculate(:sum, identity_or_column)
end end
end end

View file

@ -503,7 +503,15 @@ class CalculationsTest < ActiveRecord::TestCase
end end
def test_should_not_overshadow_enumerable_sum def test_should_not_overshadow_enumerable_sum
some_companies = companies(:rails_core).companies.order(:id)
assert_equal 6, [1, 2, 3].sum(&:abs) assert_equal 6, [1, 2, 3].sum(&:abs)
assert_equal 15, some_companies.sum(&:id)
assert_equal 25, some_companies.sum(10, &:id)
assert_deprecated do
assert_equal "LeetsoftJadedpixel", some_companies.sum(&:name)
end
assert_equal "companies: LeetsoftJadedpixel", some_companies.sum("companies: ", &:name)
end end
def test_should_sum_scoped_field def test_should_sum_scoped_field
@ -1341,12 +1349,6 @@ class CalculationsTest < ActiveRecord::TestCase
end end
end end
def test_sum_with_block_and_column_name_raises_an_error
assert_raises(ArgumentError) do
Account.sum(:firm_id) { 1 }
end
end
test "#skip_query_cache! for #pluck" do test "#skip_query_cache! for #pluck" do
Account.cache do Account.cache do
assert_queries(1) do assert_queries(1) do