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, что намного лучше для производительности.