class Account
has_many :invoices
end
class Invoice
belongs_to :account
has_many :line_items
end
def LineItem
belongs_to :invoice
end
A line_item has a total_cost.
An invoice has a total_due attribute that is the sum of all the line_items total_cost’s.
An account has a balance that is the sum of all its invoices total_due’s.
Would it be better to run these calculations every time to make sure you’re taking everything into account or should you store the sum of the children to the parent?
For instance, on each invoice, should I calculate the sum of the charges everytime via a method like:
class Invoice
## ...
def total_due
line_items.sum(:total_cost)
end
end
I like the idea of doing that, but then what would be the best way to calculate an account’s balance since you don’t have an database column storing the invoice total_due (since its a method now)? Something like:
class Account
## ...
def balance
invoices.map(&:total_due).sum
end
end
Would it be better to run these calculations every time to make sure you’re taking everything into account or should you store the sum of the children to the parent?
Unfortunately there’s no hard and fast rule here. It depends on the application. I think a good rule of thumb is to start with it as a method, and move it to a column when it’s needed, either to be able to query against it, or for performance reasons.
I like the idea of doing that, but then what would be the best way to calculate an account’s balance since you don’t have an database column storing the invoice total_due (since its a method now)?
Like this:
class Account
def balance
invoices.map(&:total_due).reduce(0, &:+)
end
end
Also, it looks like Rails extends the Ruby core on Enumerable and adds the sum method which is a shortcut for inject. And aren’t inject and reduce the same thing?
From the Rails docs:
payments.sum(&:price)
# same as
payments.inject(0) { |sum, p| sum + p.price }
Or is there a reason I should prefer to use reduce(0, &:+) over sum?