2014-06-30 21 views
16

Używam payments.sum(&:price) w mojej aplikacji Rails (4.1.2). Odkąd aktualizowany od Ruby 1.9.3 do 2.1.2, otrzymuję te błędy:suma (&: x) już nie działa

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

te działają wariantach:

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

mam do przerobienia mojego kodu lub mogę coś przeoczyć? Dziękujemy!

+2

Co to są "płatności"? Rails ma dwie różne metody "sum": [Zmienna # suma] (http://apidock.com/rails/Enumerable/sum) i [ActiveRecord :: Relation # sum] (http://api.rubyonrails.org/classes /ActiveRecord/Calculations.html#method-i-sum). Pierwszy z nich przyjmuje blok (dlatego działa '&', operator 'to_proc'; drugi nie. Niezależnie od tego, jestem pewien, że uaktualnienie Ruby z wersji 1.9.3 do 2.1 jest czerwonym śledziem. Zachowanie "&" nie zmieniło się między tymi wersjami. –

Odpowiedz

17

Z documentation:

suma (* args)

Oblicza sumę wartości w danej kolumnie. Wartość jest zwracana z tym samym typem danych kolumny, 0, jeśli nie ma wiersza. Zobacz obliczyć przykłady z opcjami.

Person.sum(:age) # => 4562 

wydaje się, że Twój kod powinien być bez &:

payments.sum(:price) 
+0

Dzięki! Wydaje się, że mój stary kod zadziałał w Rails 4.1 ... – Railsana

+1

Wydaje się, że działa to tylko na nazwach kolumn - jak szybko i łatwo można to zrobić za pomocą takich metod, jak suma działała? – Sean

+3

@ Jeśli nie używasz [szyn] (http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum), możesz po prostu użyć klasycznego ['inject'] (http: // /ruby-doc.org/core-2.1.2/Enumerable.html#method-i-inject), na przykład: 'payments.map (&: price) .inject (: +)' –

0

sum podczas używania jest to metoda zdefiniowana przez Rails na module Enumerable, nie Ruby. Aktualizacja wersji Ruby nie powinno mieć znaczenie:

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

Jednakże, jeśli używasz go podsumować kolumnę na zasadzie ActiveRecord Polecam używanie sum sposób na ActiveRecord::Relation. Możesz to zrobić, usuwając &, jak sugerują inne odpowiedzi.

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

Różnica polega na tym, że te pierwsze pobiera wszystkie rekordy z bazy danych, tworzy obiekty, wywołuje metodę price na nich i podsumowuje wyniki. Ten ostatni tworzy instrukcję SQL z SUM, która jest znacznie lepsza dla wydajności.

3

Jeśli zabrakło tego w Rails 4.0, by pojawić się następujące ostrzeżenie: Wycofanie

Wycofanie UWAGA: Wywołanie funkcja #SUM z bloku jest przestarzała i będzie być usunięte w Rails 4.1. Jeśli chcesz wykonać obliczenie sumy ponad tablicy elementów, użyj bloku "to_a.sum (&)".

Odnosi się to do metody Relation#sum, która wcześniej działała w Railsach 3.2 po nadaniu bloku.

Jak inni odpowiedział, albo trzeba użyć payments.sum(:price) jeśli cena jest kolumna bazy danych lub użyć payments.to_a.sum(&:price) jeśli price jest metoda instancji.

Powiązane problemy