I have 2 models User
and Order
. I need to generate a chart where it will retrieve monthly balance in array. In my Order
table, I have earnings
and costs
. Here is what I have come up some far:
user.rb
class User < ActiveRecord::Base
def baltime(time) #This will return balance based on time
orders.where("created_at < ?", time).map(&:earning).compact.inject(:+).to_f -
orders.live.where("created_at < ?", time).map(&:costs).compact.inject(:+).to_f
end
def group_by_months
result = []
forteenmonths = 14.times.map { |i| (Date.today - (i).month)}.reverse
forteenmonths.each do |d|
result << self.baltime(d)
end
result #This will return an array of the order balances
end
The above method is working, however, it will call 14 queries from the database. Are there any better way I can do this in order to tackle N+1 issues? Thanks in advance
Here is my way doing this with 2 queries but the code is a bit more complex. First I calculate all earnings
for 14 months and store them to an array, then subtract costs
from these months to get the final balance
of each month.
def group_by_months
earnings = orders.order(:created_at).pluck(:earning, :created_at)
costs = orders.live.order(:created_at).pluck(:cost, :created_at)
result = [0]
i = 0
date = Date.today - 13.months
earnings.each do |earning, created_at|
if created_at > date
i += 1
result[i] = result[i-1]
date = date + 1.month
end
result[i] += earning
end
i = 0
date = Date.today - 13.months
costs.each do |cost, created_at|
if created_at > date
i += 1
result[i] = result[i-1]
date = date + 1.month
end
result[i] -= cost
end
result
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.