1

This function...

class Invoice < ActiveRecord::Base

  def self.open_subtotal
    sum{ |i| i.open_amount / (1.00 + i.tax_rate / 100.00) }
  end

end

...gives me an error in Rails 4.0.2:

DEPRECATION WARNING: Calling #sum with a block is deprecated and will be removed in Rails 4.1. If you want to perform sum calculation over the array of elements, use to_a.sum(&block).

When I add to_a before sum I get an undefined local variable or method to_a error.

What is the correct way to write this?

Tintin81
  • 9,821
  • 20
  • 85
  • 178

2 Answers2

3

Apparently this is the way to do it nowadays...

select('sum(invoices.open_amount / (1.00 + invoices.tax_rate / 100.00) as open_subtotal')[0][:open_subtotal]

This does the calculations at the database level, appending as a new attribute open_subtotal which you then retrieve from the first instance of the select.

Taken from this blog.. http://stim371.github.io/blog/2014/02/12/deprecating-blocks-on-activerecord-count-and-sum/

SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53
1

This would work:

def self.open_subtotal
  all.to_a.sum { |i| i.open_amount / (1.00 + i.tax_rate / 100.00) }
end

But you can probably sum it in SQL (assuming open_amount and tax_rate are fields in your invoices table):

def self.open_subtotal
  sum("open_amount / (1 + tax_rate / 100)")
end
Stefan
  • 109,145
  • 14
  • 143
  • 218