Sum (&: x) больше не работает

Я использую payments.sum(&:price) в моем приложении Rails (4.1.2). Поскольку я обновляюсь с Ruby 1.9.3 до 2.1.2, я получаю следующие ошибки:

wrong number of arguments (1 for 2..3)

Эти варианты работают:

payments.map(&:price).sum
payments.to_a.sum(&:price)

Должен ли я переписать свой код или мне что-то не хватает? Спасибо!

Ответы

Ответ 1

Из документации:

сумма (* арг)

Вычисляет сумму значений в данном столбце. Значение возвращается с тем же типом данных столбца, 0, если нет строки. Видеть рассчитать примеры с опциями.

Person.sum(:age) # => 4562

кажется, что ваш код должен быть без &:

payments.sum(:price)

Ответ 2

Если вы запустили это в Rails 4.0, вы получите следующее предупреждение об отказе:

ПРЕДУПРЕЖДЕНИЕ О ДЕПРЕКАЦИИ: Вызов #sum с блоком устарел и будет удаляться в Rails 4.1. Если вы хотите выполнить вычисление суммы за массив элементов, используйте 'to_a.sum(& блок).

Это относится к методу Relation#sum, который ранее работал в Rails 3.2 при задании блока.

Как ответили другие, вам нужно либо использовать payments.sum(:price), если цена является столбцом базы данных, либо использовать payments.to_a.sum(&:price), если price - это метод экземпляра.

Ответ 3

Если платежи являются ассоциацией ActiveRecord, вы можете вместо этого использовать ActiveRecord:: Calculations sum:

payments.sum(:price)

Ответ 4

sum, поскольку вы используете это метод в модуле Enumerable, определенный Rails, а не Ruby. Обновление версий рубинов не должно иметь значения:

http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum

Однако, если вы используете его для суммирования столбца в ActiveRecord, я рекомендую использовать метод sum на ActiveRecord::Relation. Вы можете сделать это, удалив &, как указывают другие ответы.

http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-sum

Разница в том, что первая извлекает все записи из базы данных, создает объекты, называет метод price на них и суммирует результаты. Последний создает SQL-запрос с SUM, что намного лучше для производительности.