N + 1查询问题

时间:2016-07-30 01:43:53

标签: sql ruby-on-rails arrays activerecord

我有2个模型UserOrder。我需要生成一个图表,它将在数组中检索每月余额。在我的Order表中,我有earningscosts。以下是我的发展方向:

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

上述方法正在运行,但是,它将从数据库中调用14个查询。有没有更好的方法来解决N + 1问题?提前致谢

1 个答案:

答案 0 :(得分:0)

这是我使用2个查询执行此操作的方法,但代码有点复杂。首先,我计算14个月的所有earnings并将它们存储到数组中,然后从这些月中减去costs以获得每个月的最终balance

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